home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / CRS / crs49.d81 / hack8b.sfx / issue8b
Text File  |  1990-02-12  |  91KB  |  2,422 lines

  1. ╨LOTTING A POINT
  2. ----------------
  3.  
  4. ╔N THE LINE ROUTINE PRESENTED EARLIER, THE NEBULOUS STATEMENT ╨╨╠╧╘ WAS
  5. WRITTEN.  ╬OW WE COME TO PLOTTING A POINT IN ALL ITS GORY DETAIL.
  6.  
  7. ╞OR THIS PROJECT, SPEED IS THE NAME OF THE GAME, AND FOR SPEED WE DON'T WANT
  8. TO USE NORMAL BITMAPPED GRAPHICS.  ╔NSTEAD, WE WANT TO USE CHARACTER
  9. GRAPHICS.  ╘HE ADVANTAGES OF USING A CUSTOM CHARACTER SET ARE:
  10.  
  11.         - ╠ESS MEMORY
  12.         - ╙PEED OF PLOTTING
  13.         - ─OUBLE BUFFERING
  14.         - ├ONVENIENT ORGANIZATION
  15.  
  16. ╘HE FIRST ADVANTAGE, LESS MEMORY, SHOULD BE CLEAR.  ┴ CUSTOM CHARACTER SET
  17. TAKES UP 2K.  ┴ BITMAP, ON THE OTHER HAND, TAKES UP 8K.
  18.  
  19. ╞OR THE SECOND ADVANTAGE, IT IS MUCH FASTER TO POKE A CHARACTER INTO SCREEN
  20. MEMORY THAN IT IS TO CALCULATE AND PLOT ALL 64 BITS IN A CHARACTER.  ╘HIS
  21. WAY, ╓╔├ DOES ALL THE HARD WORK FOR US.  ┴LSO, IF WE ARE CLEVER, WE CAN
  22. EXPLOIT SEVERAL ASPECTS OF OUR CLEVERNESS TO MAKE PLOTTING A SINGLE POINT
  23. MUCH EASIER.
  24.  
  25. ├HARACTER GRAPHICS ALSO GIVE US A VERY SIMPLE MEANS OF DOUBLE BUFFERING: WE
  26. CAN JUST PLOT INTO TWO DIFFERENT CHARACTER SETS AND TELL ╓╔├-╔╔ TO MOVE
  27. BETWEEN THEM.  ╬O RASTER INTERRUPTS HERE!  ╔F THE TWO CHARACTER SETS WERE AT
  28. $3000 AND $3800, HERE IS HOW TO SWITCH BETWEEN THEM:
  29.  
  30.         ╠─┴ ╓═├╙┬       ;╓═├╙┬=$─018
  31.         ┼╧╥ #%00000010  ;╞LIP THE BIT
  32.         ╙╘┴ ╓═├╙┬
  33.  
  34. ╘RUE, CLEARING THE BUFFER EACH TIME IS A BIT SLOW, BUT FOR OUR PURPOSES IT
  35. WILL DO JUST FINE.
  36.  
  37. ╘HE LAST IS LESS OBVIOUS.  ┴ NORMAL HIRES BITMAP IS ORGANIZED LIKE THE
  38. FOLLOWING:
  39.  
  40.         00  08 ...
  41.         01  09
  42.         02  0┴
  43.         ... ...
  44.         07  0╞
  45.  
  46. WHERE THE NUMBER REPRESENTS THE OFFSET OF THE BYTE.  ╘HIS IS FINE FOR SOME
  47. THINGS, BUT CALCULATING THE POSITION OF A PIXEL IS TRICKY.  ╫ITH A CHARACTER
  48. MAP, WE CAN REPRESENT OUR DATA ANY WAY WE WANT.  ╔N PARTICULAR, WE CAN
  49. ORGANIZE OUR BITMAP TO LOOK LIKE THE FOLLOWING:
  50.  
  51.         00  80  ...
  52.         01  81
  53.         02  82
  54.         ... ...
  55.         7─  ╞─
  56.         7┼  ╞┼
  57.         7╞  ╞╞  ...
  58.  
  59. ╧R, IN GRAPHIC FORM
  60.  
  61.         @╨... ETC.
  62.         ┴╤
  63.         ┬╥
  64.         ├╙ 
  65.         ..
  66.         ╧<-  (THE BACK-ARROW)
  67.  
  68. ╫HAT WE HAVE DONE IS, INSTEAD OF PUTTING CHARACTERS SIDE-BY-SIDE LIKE A
  69. HIRES BITMAP DOES, WE PUT THEM ON TOP OF EACH OTHER.  ╘HE ABOVE REPRESENTS A
  70. 16X16 CHARACTER ARRAY, WHICH IS A 128X128 PIXEL ARRAY. ╬OW THE Y-COORDINATE
  71. IS A DIRECT INDEX INTO THE ROW WE ARE IN.  ╘HAT IS, BASE+┘ = MEMORY LOCATION
  72. OF POINT.
  73.  
  74. ╘HIS BRINGS US TO THE PRIMARY DISADVANTAGE OF USING A CHARACTER SET: OUR
  75. PICTURES ARE PRETTY SMALL.  ╘┴╬╙╙┴┴╞╠.
  76.  
  77. ╬OW WE COULD JUST GO MERRILY PLOTTING INTO OUR CHARACTER BITMAP, BUT AS
  78. USUAL A LITTLE THOUGHT CAN YIELD SOME IMPRESSIVE RETURN.  ╘HE FIRST THING TO
  79. NOTICE IS THAT THE MAXIMUM VALUE FOR Y IS 127; THE ONLY THING THAT SETS THE
  80. HIGH BIT IS THE X-COORDINATE, AND THEN ONLY WHEN IT CROSSES A COLUMN (JUST
  81. LOOK AT THE ABOVE MEMORY MAP IF YOU DON'T SEE IT).
  82.  
  83. ╘HEREFORE, IF WE COULD KEEP TRACK OF THE BIT POSITION OF X, WE COULD TELL
  84. WHEN X CROSSED A COLUMN, AND JUST ADD 128 TO THE BASE ADDRESS.  ╬OT ONLY
  85. THAT, BUT WE ALSO KNOW TO INCREASE THE HIGH BYTE OF THE POINTER BY ONE WHEN
  86. WE HAVE CROSSED TWO COLUMNS.
  87.  
  88. ╘HE LOGIC IS AS FOLLOWS:
  89.         - ╞IND THE BIT PATTERN FOR A GIVEN X (FOR SPEED, USE A TABLE)
  90.         - ╔F IT IS 10000000 THEN WE HAVE JUMPED A COLUMN
  91.         - ╔F THE COLUMN WE ARE IN DOESN'T HAVE THE HIGH BIT SET
  92.           IN THE LOW BYTE OF THE POINTER TO THE BASE OF THE COLUMN,
  93.           THEN SET THE HIGH BIT (ADD 128)
  94.         - ╧THERWISE, SET THE HIGH BIT TO ZERO (ADD 128), AND INCREASE
  95.           THE HIGH BYTE OF THE COLUMN POINTER (STEP INTO THE NEXT PAGE).
  96.  
  97. ╚ERE IS (MORE OR LESS) THE CODE:
  98.  
  99. ╔N ┬┴╙╔├:
  100.         2000 REM BP(X) CONTAINS BIT POSITION FOR X
  101.         2010 IF INT(X/8) = X/8 THEN BASE=BASE+128
  102.         2020 POKE BASE+Y, (PEEK(BASE+Y) OR BP(X))
  103.  
  104. ╔N ASSEMBLY:
  105.         ╠─┴     ┬╔╘╨,╪  4       ;╠OAD THE BIT PATTERN FROM A TABLE
  106.         ┬╨╠     ├╧╬╘    3  2    ;╙TILL IN THE SAME COLUMN?
  107.         ┼╧╥     $╠╧        3    ;╔F NOT, ADD 128 TO THE LOW BYTE
  108.         ╙╘┴     $╠╧        3
  109.         ┬═╔     ├╧╬╘       3  2 ;╔F THE HIGH BIT IS SET, STAY IN THE SAME PAGE
  110.         ╔╬├     $╚╔           5 ;╧THERWISE POINT TO THE NEXT PAGE
  111.         ╠─┴     #$128         2 ;╫E STILL NEED THE BIT PATTERN FOR X!
  112.    ├╧╬╘ ╧╥┴     ($╠╧),┘ 5
  113.         ╙╘┴     ($╠╧),┘ 6       ;╨LOT THE POINT
  114.                         --------
  115.            ├YCLE COUNT: 18 26 32
  116.  
  117. ╘HEREFORE, IT TAKES 18 CYCLES TO PLOT A POINT, 26 CYCLES TO JUMP A COLUMN,
  118. AND 32 CYCLES TO JUMP A PAGE.  ╧VER 16 POINTS, THIS AVERAGES 19.375 CYCLES.
  119.  
  120. ╫HEN COMBINED WITH THE EARLIER LINE DRAWING ROUTINE, THIS GIVES AN AVERAGE
  121. TIME OF 38 CYCLES OR SO (WITH A BEST TIME OF 34 CYCLES); SIX OF THOSE CYCLES
  122. ARE FOR ╨╚┴ AND ╨╠┴, SINCE THE LINE DRAWING ROUTINE USES ┴ FOR OTHER THINGS.
  123.  
  124. ╠IKE MOST OF THE CODE, YOU CAN IMPROVE ON THIS METHOD IF YOU THINK ABOUT IT
  125. A LITTLE.  ═OST OF THE TIME IS SPENT CHECKING THE SPECIAL CASES, SO HOW CAN
  126. YOU AVOID THEM?  ═AYBE IF WE DO ANOTHER ARTICLE, WE'LL SHOW YOU OUR
  127. SOLUTION(S).
  128.  
  129. ╬OW, THIS METHOD HAS A FEW SUBTLETIES ABOUT IT.  ╞IRST, WHAT HAPPENS IF THE
  130. FIRST POINT TO BE PLOTTED IS X=0, OR X=8?  ╘HE ABOVE ROUTINE WILL INCREASE
  131. THE BASE POINTER RIGHT OFF THE BAT.  ╘HIS CASE NEEDS TO BE TAKEN CARE OF.
  132.  
  133. ╙ECOND, THE ABOVE ASSUMES THAT YOU ALWAYS TAKE A STEP IN X.  ╫HAT HAPPENS IF
  134. WE ARE TAKING A BIG STEP IN Y?  ╠ET'S SAY THAT WE TAKE TEN STEPS IN Y FOR
  135. EVERY STEP IN X.  ╫HAT WILL THE ABOVE PLOTTER DO IF X TAKES A STEP ACROSS A
  136. COLUMN, AND THEN DOESN'T CHANGE FOR A WHILE? ╠OOK TO THE SOURCE CODE FOR ONE
  137. SOLUTION TO THIS PROBLEM.
  138.  
  139. ╙O THAT'S ALL THERE IS TO IT!
  140.  
  141. ╨OST ╙CRIPT
  142. -----------
  143.  
  144. ╘HAT'S ALL THERE IS TO IT.  ╫ELL, ╧╦, THERE ARE A FEW DETAILS WE LEFT OUT,
  145. BUT YOU CAN FIGURE THEM OUT ON YOUR OWN.  ┘OU CAN ALWAYS LOOK TO THE SOURCE
  146. CODE TO SEE HOW WE OVERCAME THE SAME PROBLEM.  ╘HE PROGRAM IS SET UP IN A
  147. WAY THAT YOU CAN EXPERIMENT AROUND WITH THE PROJECTION PARAMETERS D AND Z0,
  148. TO SEE WHAT CHANGING THEM DOES TO THE MATH.
  149.  
  150. ╫HAT'S NEXT?  ╔N THE FUTURE YOU WILL UNDOUBTABLY SEE LOTS OF THINGS FROM
  151. ╟EORGE AND MYSELF, BOTH THE WRITTEN WORD AND THE CODED BYTE.  ═AYBE WE WILL
  152. SEE SOMETHING FROM YOU AS WELL?
  153.  
  154. ─A ├ODE
  155. -------
  156.  
  157. ********************************
  158. *..............................*
  159. *.╙TEPHEN.╩UDD.................*
  160. *.╟EORGE.╘AYLOR................*
  161. *.╙TARTED:.7/11/94.............*
  162. *.╞INISHED:.7/19/94............*
  163. *..............................*
  164. *.╫ELL,.IF.ALL.GOES.WELL.THIS..*
  165. *.PROGRAM.WILL.ROTATE.A.CUBE...*
  166. *..............................*
  167. *.╘HIS.PROGRAM.IS.INTENDED.TO..*
  168. *.ACCOMPANY.THE.ARTICLE.IN.....*
  169. *.├=╚ACKING,.╩ULY.94.ISSUE.....*
  170. *.╞OR.DETAILS.ON.THIS.PROGRAM,.*
  171. *.READ.THE.ARTICLE!............*
  172. *..............................*
  173. *.╫RITE.TO.US!.................*
  174. *..............................*
  175. *.UN(BEE)MO....................*
  176. *..............................*
  177. *.VI...........................*
  178. *.N(IN)G.......................*
  179. *.ARE(TH.......................*
  180. *.E)YOU(O......................*
  181. *.NLY).........................*
  182. *..............................*
  183. *.ASL(ROSE)EEP.................*
  184. *..............E.E.CUMMINGS....*
  185. *..............................*
  186. *.╨.╙..╘HIS.WAS.WRITTEN.USING..*
  187. *......═ERLIN.128...╫ITH.A.....*
  188. *......LITTLE.MODIFICATION.IT..*
  189. *......WILL.WORK.FINE.WITH.....*
  190. *......═ERLIN.64...╔F.YOU......*
  191. *......DON'T.HAVE.EITHER.......*
  192. *......WELL,.WE.ALL.HAVE.OUR...*
  193. *......LITTLE.FAULTS...........*
  194. ********************************
  195.  
  196.  ╧╥╟ $1000
  197.  
  198. *.├ONSTANTS
  199.  
  200. ┬╒╞╞1 ┼╤╒ $3000 ;╞IRST.CHARACTER.SET
  201. ┬╒╞╞2 ┼╤╒ $3800 ;╙ECOND.CHARACTER.SET
  202. ┬╒╞╞┼╥ ┼╤╒ $┴3 ;╨RESUMABLY.THE.TAPE.WON'T.BE.RUNNING
  203. ╪1 ┼╤╒ $╞┬ ;╨OINTS.FOR.DRAWING.A.LINE
  204. ┘1 ┼╤╒ $╞├ ;╘HESE.ZERO.PAGE.ADDRESSES
  205. ╪2 ┼╤╒ $╞─ ;DON'T.CONFLICT.WITH.┬┴╙╔├
  206. ┘2 ┼╤╒ $╞┼
  207. ─╪ ┼╤╒ $╞9
  208. ─┘ ┼╤╒ $╞┴
  209. ╘┼═╨1 ┼╤╒ $╞┬ ;╧F.COURSE,.COULD.CONFLICT.WITH.X1
  210. ╘┼═╨2 ┼╤╒ $╞├ ;╘EMPORARY.VARIABLES
  211. ┴├├ ┼╤╒ $╞┬ ;╘HESE.FOUR.VARIABLES.ARE.USED
  212. ┴╒╪ ┼╤╒ $╞├ ;BY.THE.MULTIPLICATION.ROUTINE
  213. ┼╪╘ ┼╤╒ $╞─
  214. ╥┼═ ┼╤╒ $╞┼
  215. ┌╘┼═╨ ┼╤╒ $02 ;╒SED.FOR.BUFFER.SWAP...─ON'T.TOUCH.
  216.  
  217. ┴╬╟═┴╪ ┼╤╒ 120 ;╘HERE.ARE.2*PI/ANGMAX.ANGLES
  218. ╧╞╞╙┼╘ ┼╤╒ 6 ;╞LOAT.OFFSET:.X=XACTUAL*2^OFFSET
  219.  
  220. *.╓╔├
  221.  
  222. ╓═├╙┬ ┼╤╒ $─018
  223. ┬╦╟╬─ ┼╤╒ $─020
  224. ┬╧╥─┼╥ ┼╤╒ $─021
  225. ╙╙╘┴╥╘ ┼╤╒ 1344 ;ROW.9.IN.SCREEN.MEMORY.AT.1024
  226.  
  227.  
  228. *.╦ERNAL
  229.  
  230. ├╚╥╧╒╘ ┼╤╒ $╞╞─2
  231. ╟┼╘╔╬ ┼╤╒ $╞╞┼4
  232.  
  233. ***.═ACROS
  234.  
  235. ═╧╓┼ ═┴├
  236.  ╠─┴ ]1
  237.  ╙╘┴ ]2
  238.  <<<
  239.  
  240. ╟┼╘╦┼┘ ═┴├  ;╫AIT.FOR.A.KEYPRESS
  241. ╫┴╔╘ ╩╙╥ ╟┼╘╔╬
  242.  ├═╨ #00
  243.  ┬┼╤ ╫┴╔╘
  244.  <<<
  245.  
  246. ─┼┬╒╟ ═┴├  ;╨RINT.A.CHARACTER
  247. . ─╧.0  ;─ON'T.ASSEMBLE
  248.  
  249.  ╠─┴ #]1
  250.  ╩╙╥ ├╚╥╧╒╘
  251.  >>> ╟┼╘╦┼┘ ;┴ND.WAIT.TO.CONTINUE
  252.  ├═╨ #'S' ;═Y.SECRECT.SWITCH.KEY
  253.  ┬╬┼ ╠1
  254.  ╩╙╥ ├╠┼┴╬╒╨
  255.  ╩═╨ ─╧╬┼
  256. ╠1 ├═╨ #'X' ;═Y.SECRET.ABORT.KEY
  257.  ┬╬┼ ─╧╬┼
  258.  ╩═╨ ├╠┼┴╬╒╨
  259.  ╞╔╬
  260. ─╧╬┼ <<<
  261.  
  262. ─┼┬╒╟┴ ═┴├
  263.  ─╧.0
  264.  ╠─┴ ]1
  265.  ╙╘┴ 1024
  266.  ╞╔╬
  267. ─╧╬┼┴ <<<
  268.  
  269. ╙┼╘┬╒╞ ═┴├  ;╨UT.BUFFERS.WHERE.THEY.CAN.BE.HURT
  270.  ╠─┴ #00
  271.  ╙╘┴ ┬╒╞╞┼╥
  272.  ╠─┴ ┌╘┼═╨ ;ZTEMP.CONTAINS.THE.HIGH.BYTE.HERE
  273.  ╙╘┴ ┬╒╞╞┼╥+1
  274.  <<<
  275.  
  276. *-------------------------------
  277.  
  278.  ╠─┴ #$00
  279.  ╙╘┴ ┬╦╟╬─
  280.  ╙╘┴ ┬╧╥─┼╥
  281.  ╠─┴ ╓═├╙┬
  282.  ┴╬─ #%00001111 ;╙CREEN.MEMORY.TO.1024
  283.  ╧╥┴ #%00010000
  284.  ╙╘┴ ╓═├╙┬
  285.  
  286.  ╠─┘ #00
  287.  ╠─┴ #<╘╘┼╪╘
  288.  ╙╘┴ ╘┼═╨1
  289.  ╠─┴ #>╘╘┼╪╘
  290.  ╙╘┴ ╘┼═╨2
  291.  ╩═╨ ╘╔╘╠┼
  292. ╘╘┼╪╘ ╚┼╪ 9305111111 ;CLEAR.SCREEN,.WHITE,.CRSR.DN
  293.  ╘╪╘ '...............CUBE3D',0D,0D
  294.  ╘╪╘ '.................BY',0D
  295.  ╚┼╪ 9╞ ;CYAN
  296.  ╘╪╘ '....STEPHEN.JUDD'
  297.  ╚┼╪ 99
  298.  ╘╪╘ '....GEORGE.TAYLOR',0D,0D
  299.  ╚┼╪ 9┬
  300.  ╘╪╘ '..CHECK.OUT.THE.JULY.94.ISSUE.OF',0D
  301.  ╚┼╪ 96
  302.  ╘╪╘ '..C=HACKING'
  303.  ╚┼╪ 9┬
  304.  ╘╪╘ '.FOR.MORE.DETAILS!',0D
  305.  ╚┼╪ 0─1─1─9┼12
  306.  ╘╪╘ 'F1/F2',92
  307.  ╘╪╘ '.-.INC/DEC.X-ROTATION',0D
  308.  ╚┼╪ 1─1─12
  309.  ╘╪╘ 'F3/F4',92
  310.  ╘╪╘ '.-.INC/DEC.Y-ROTATION',0D
  311.  ╚┼╪ 1─1─12
  312.  ╘╪╘ 'F5/F6',92
  313.  ╘╪╘ '.-.INC/DEC.Z-ROTATION',0D
  314.  ╚┼╪ 1─1─12
  315.  ╘╪╘ 'F7',92
  316.  ╘╪╘ '.RESETS',0D
  317.  ╘╪╘ '..PRESS.Q.TO.QUIT',0D
  318.  ╚┼╪ 0─05
  319.  ╘╪╘ '......PRESS.ANY.KEY.TO.BEGIN',0D
  320.  ╚┼╪ 00
  321. ╘╔╘╠┼ ╠─┴ (╘┼═╨1),┘
  322.  ┬┼╤ :├╧╬╘
  323.  ╩╙╥ ├╚╥╧╒╘
  324.  ╔╬┘
  325.  ┬╬┼ ╘╔╘╠┼
  326.  ╔╬├ ╘┼═╨2
  327.  ╩═╨ ╘╔╘╠┼
  328. :├╧╬╘ >>> ╟┼╘╦┼┘
  329.  
  330. ****.╙ET.UP.TABLES(?)
  331.  
  332. *.╘ABLES.ARE.CURRENTLY.SET.UP.IN.┬┴╙╔├
  333. *.AND.BY.THE.ASSEMBLER.
  334.  
  335. ╘┴┬╠┼╙
  336.  
  337. ****.├LEAR.SCREEN.AND.SET.UP."BITMAP"
  338.  
  339. ╙┼╘╒╨ ╠─┴ #147
  340.  ╩╙╥ ├╚╥╧╒╘
  341.  ╠─┴ #<╙╙╘┴╥╘
  342.  ┴─├ #12 ;╘HE.GOAL.IS.TO.CENTER.THE.GRAPHICS
  343.  ╙╘┴ ╘┼═╨1 ;├OLUMN.12
  344.  ╠─┴ #>╙╙╘┴╥╘ ;╥OW.9
  345.  ╙╘┴ ╘┼═╨1+1 ;╙╙╘┴╥╘.POINTS.TO.ROW.9
  346.  ╠─┴ #00
  347.  ╠─┘ #00
  348.  ╠─╪ #00 ;X.WILL.COUNT.16.ROWS.FOR.US
  349.  ├╠├
  350.  
  351. :╠╧╧╨ ╙╘┴ (╘┼═╨1),┘
  352.  ╔╬┘
  353.  ┴─├ #16
  354.  ┬├├ :╠╧╧╨
  355.  ├╠├
  356.  ╠─┴ ╘┼═╨1
  357.  ┴─├ #40 ;╬EED.TO.ADD.40.TO.THE.BASE.POINTER
  358.  ╙╘┴ ╘┼═╨1 ;╘O.JUMP.TO.THE.NEXT.ROW
  359.  ╠─┴ ╘┼═╨1+1
  360.  ┴─├ #00 ;╘AKE.CARE.OF.CARRIES
  361.  ╙╘┴ ╘┼═╨1+1
  362.  ╠─┘ #00
  363.  ╔╬╪
  364.  ╘╪┴  ;╪.IS.ALSO.AN.INDEX.INTO.THE.CHARACTER.NUMBER
  365.  ├╨╪ #16
  366.  ┬╬┼ :╠╧╧╨ ;╬EED.TO.DO.IT.16.TIMES
  367.  
  368.  >>> ─┼┬╒╟,'2'
  369. ****.╙ET.UP.BUFFERS
  370.  
  371.  ╠─┴ #<┬╒╞╞1
  372.  ╙╘┴ ┬╒╞╞┼╥
  373.  ╠─┴ #>┬╒╞╞1
  374.  ╙╘┴ ┬╒╞╞┼╥+1
  375.  ╙╘┴ ┌╘┼═╨ ;ZTEMP.WILL.MAKE.LIFE.SIMPLE.FOR.US
  376.  ╠─┴ ╓═├╙┬
  377.  ┴╬─ #%11110001 ;╙TART.HERE.SO.THAT.SWAP.BUFFERS.WILL.WORK.RIGHT
  378.  ╧╥┴ #%00001110
  379.  ╙╘┴ ╓═├╙┬
  380.  
  381.  
  382. ****.╙ET.UP.INITIAL.VALUES
  383.  
  384. ╔╬╔╘ ╠─┴ #00
  385.  ╙╘┴ ─╙╪
  386.  ╙╘┴ ─╙┘
  387.  ╙╘┴ ─╙┌
  388.  ╙╘┴ ╙╪
  389.  ╙╘┴ ╙┘
  390.  ╙╘┴ ╙┌
  391.  
  392.  >>> ─┼┬╒╟,'4'
  393.  
  394. *-------------------------------
  395. *.═AIN.LOOP
  396.  
  397. ****.╟ET.KEYPRESS
  398.  
  399. ═┴╔╬
  400. ╦╨╥┼╙╙ ╩╙╥ ╟┼╘╔╬
  401.  ├═╨ #133 ;╞1?
  402.  ┬╬┼ :╞2
  403.  ╠─┴ ─╙╪
  404.  ├═╨ #┴╬╟═┴╪/2 ;╬O.MORE.THAN.PI
  405.  ┬┼╤ :├╧╬╘
  406.  ╔╬├ ─╙╪ ;OTHERWISE.INCREASE.X-ROTATION
  407.  ╩═╨ :├╧╬╘
  408. :╞2 ├═╨ #137 ;╞2?
  409.  ┬╬┼ :╞3
  410.  ╠─┴ ─╙╪
  411.  ┬┼╤ :├╧╬╘
  412.  ─┼├ ─╙╪
  413.  ╩═╨ :├╧╬╘
  414. :╞3 ├═╨ #134
  415.  ┬╬┼ :╞4
  416.  ╠─┴ ─╙┘
  417.  ├═╨ #┴╬╟═┴╪/2
  418.  ┬┼╤ :├╧╬╘
  419.  ╔╬├ ─╙┘ ;╔NCREASE.Y-ROTATION
  420.  ╩═╨ :├╧╬╘
  421. :╞4 ├═╨ #138
  422.  ┬╬┼ :╞5
  423.  ╠─┴ ─╙┘
  424.  ┬┼╤ :├╧╬╘
  425.  ─┼├ ─╙┘
  426.  ╩═╨ :├╧╬╘
  427. :╞5 ├═╨ #135
  428.  ┬╬┼ :╞6
  429.  ╠─┴ ─╙┌
  430.  ├═╨ #┴╬╟═┴╪/2
  431.  ┬┼╤ :├╧╬╘
  432.  ╔╬├ ─╙┌ ;Z-ROTATION
  433.  ╩═╨ :├╧╬╘
  434. :╞6 ├═╨ #139
  435.  ┬╬┼ :╞7
  436.  ╠─┴ ─╙┌
  437.  ┬┼╤ :├╧╬╘
  438.  ─┼├ ─╙┌
  439.  ╩═╨ :├╧╬╘
  440. :╞7 ├═╨ #136
  441.  ┬╬┼ :╤
  442.  ╩═╨ ╔╬╔╘
  443. :╤ ├═╨ #'Q' ;Q.QUITS
  444.  ┬╬┼ :├╧╬╘
  445.  ╩═╨ ├╠┼┴╬╒╨
  446.  
  447. :├╧╬╘
  448. *.>>>.─┼┬╒╟,'5'
  449.  
  450. ****.╒PDATE.ANGLES
  451.  
  452. ╒╨─┴╘┼ ├╠├
  453.  ╠─┴ ╙╪
  454.  ┴─├ ─╙╪
  455.  ├═╨ #┴╬╟═┴╪ ;┴RE.WE.>=.MAXIMUM.ANGLE?
  456.  ┬├├ :├╧╬╘1
  457.  ╙┬├ #┴╬╟═┴╪ :╔F SO, RESET
  458. :├╧╬╘1 ╙╘┴ ╙╪
  459.  ├╠├
  460.  ╠─┴ ╙┘
  461.  ┴─├ ─╙┘
  462.  ├═╨ #┴╬╟═┴╪
  463.  ┬├├ :├╧╬╘2
  464.  ╙┬├ #┴╬╟═┴╪ ;╙AME.DEAL
  465. :├╧╬╘2 ╙╘┴ ╙┘
  466.  ├╠├
  467.  ╠─┴ ╙┌
  468.  ┴─├ ─╙┌
  469.  ├═╨ #┴╬╟═┴╪
  470.  ┬├├ :├╧╬╘3
  471.  ╙┬├ #┴╬╟═┴╪
  472. :├╧╬╘3 ╙╘┴ ╙┌
  473.  
  474.  
  475. ****.╥OTATE.COORDINATES
  476.  
  477. ╥╧╘┴╘┼
  478.  
  479. ***.╞IRST,.CALCULATE.T1,T2,...,T10
  480.  
  481. **.╘WO.MACROS.TO.SIMPLIFY.OUR.LIFE
  482. ┴──┴ ═┴├  ;┴DD.TWO.ANGLES.TOGETHER
  483.  ├╠├
  484.  ╠─┴ ]1
  485.  ┴─├ ]2
  486.  ├═╨ #┴╬╟═┴╪ ;╔S.THE.SUM.>.2*PI?
  487.  ┬├├ ─╧╬┼
  488.  ╙┬├ #┴╬╟═┴╪ ;╔F.SO,.SUBTRACT.2*PI
  489. ─╧╬┼ <<<
  490.  
  491. ╙╒┬┴ ═┴├  ;╙UBTRACT.TWO.ANGLES
  492.  ╙┼├
  493.  ╠─┴ ]1
  494.  ╙┬├ ]2
  495.  ┬├╙ ─╧╬┼
  496.  ┴─├ #┴╬╟═┴╪ ;╧OPS,.WE.NEED.TO.ADD.2*PI
  497. ─╧╬┼ <<<
  498.  
  499. **.╬OW.CALCULATE.T1,T2,ETC.
  500.  
  501.  >>> ╙╒┬┴,╙┘;╙┌
  502.  ╙╘┴ ╘1 ;T1=SY-SZ
  503.  >>> ┴──┴,╙┘;╙┌
  504.  ╙╘┴ ╘2 ;T2=SY+SZ
  505.  >>> ┴──┴,╙╪;╙┌
  506.  ╙╘┴ ╘3 ;T3=SX+SZ
  507.  >>> ╙╒┬┴,╙╪;╙┌
  508.  ╙╘┴ ╘4 ;T4=SX-SZ
  509.  >>> ┴──┴,╙╪;╘2
  510.  ╙╘┴ ╘5 ;T5=SX+T2
  511.  >>> ╙╒┬┴,╙╪;╘1
  512.  ╙╘┴ ╘6 ;T6=SX-T1
  513.  >>> ┴──┴,╙╪;╘1
  514.  ╙╘┴ ╘7 ;T7=SX+T1
  515.  >>> ╙╒┬┴,╘2;╙╪
  516.  ╙╘┴ ╘8 ;T8=T2-SX
  517.  >>> ╙╒┬┴,╙┘;╙╪
  518.  ╙╘┴ ╘9 ;T9=SY-SX
  519.  >>> ┴──┴,╙╪;╙┘
  520.  ╙╘┴ ╘10 ;T10=SX+SY
  521.  
  522. *.┼T.VOILA!
  523.  
  524. ***.╬EXT,.CALCULATE.┴,┬,├,...,╔
  525.  
  526. **.┴NOTHER.USEFUL.LITTLE.MACRO
  527. ─╔╓2 ═┴├  ;─IVIDE.A.SIGNED.NUMBER.BY.2
  528. ;╔T.IS.ASSUMED.THAT.THE.NUMBER
  529.  ┬╨╠ ╨╧╙ ;IS.IN.THE.ACCUMULATOR
  530.  ├╠├
  531.  ┼╧╥ #$╞╞ ;╫E.NEED.TO.UN-NEGATIVE.THE.NUMBER
  532.  ┴─├ #01 ;BY.TAKING.IT'S.COMPLEMENT
  533.  ╠╙╥  ;DIVIDE.BY.TWO
  534.  ├╠├
  535.  ┼╧╥ #$╞╞
  536.  ┴─├ #01 ;═AKE.IT.NEGATIVE.AGAIN
  537.  ╩═╨ ─╧╬┼─╔╓
  538. ╨╧╙ ╠╙╥  ;╬UMBER.IS.POSITIVE
  539. ─╧╬┼─╔╓ <<<
  540.  
  541. ═╒╠2 ═┴├  ;═ULTIPLY.A.SIGNED.NUMBER.BY.2
  542.  ┬╨╠ ╨╧╙═
  543.  ├╠├
  544.  ┼╧╥ #$╞╞
  545.  ┴─├ #$01
  546.  ┴╙╠
  547.  ├╠├
  548.  ┼╧╥ #$╞╞
  549.  ┴─├ #$01
  550.  ╩═╨ ─╧╬┼═╒╠
  551. ╨╧╙═ ┴╙╠
  552. ─╧╬┼═╒╠ <<<
  553.  
  554. **.╬OTE.THAT.WE.ARE.CURRENTLY.MAKING.A.MINOR.LEAP
  555. **.OF.FAITH.THAT.NO.OVERFLOWS.WILL.OCCUR.
  556.  
  557. :├┴╠├┴ ├╠├
  558.  ╠─╪ ╘1
  559.  ╠─┴ ├╧╙,╪
  560.  ╠─╪ ╘2
  561.  ┴─├ ├╧╙,╪
  562.  ╙╘┴ ┴11 ;┴=(COS(T1)+COS(T2))/2
  563. :├┴╠├┬ ╠─╪ ╘1
  564.  ╠─┴ ╙╔╬,╪
  565.  ╙┼├
  566.  ╠─╪ ╘2
  567.  ╙┬├ ╙╔╬,╪
  568.  ╙╘┴ ┬12 ;┬=(SIN(T1)-SIN(T2))/2
  569. :├┴╠├├ ╠─╪ ╙┘
  570.  ╠─┴ ╙╔╬,╪
  571.  >>> ═╒╠2
  572.  ╙╘┴ ├13 ;├=SIN(SY)
  573. :├┴╠├─ ╙┼├
  574.  ╠─╪ ╘8
  575.  ╠─┴ ├╧╙,╪
  576.  ╠─╪ ╘7
  577.  ╙┬├ ├╧╙,╪
  578.  ╙┼├
  579.  ╠─╪ ╘5
  580.  ╙┬├ ├╧╙,╪
  581.  ├╠├
  582.  ╠─╪ ╘6
  583.  ┴─├ ├╧╙,╪ ;─I=(COS(T8)-COS(T7)+COS(T6)-COS(T5))/2
  584.  >>> ─╔╓2
  585.  ├╠├
  586.  ╠─╪ ╘3
  587.  ┴─├ ╙╔╬,╪
  588.  ╙┼├
  589.  ╠─╪ ╘4
  590.  ╙┬├ ╙╔╬,╪
  591.  ╙╘┴ ─21 ;─=(SIN(T3)-SIN(T4)+─I)/2
  592. :├┴╠├┼ ╙┼├
  593.  ╠─╪ ╘5
  594.  ╠─┴ ╙╔╬,╪
  595.  ╠─╪ ╘6
  596.  ╙┬├ ╙╔╬,╪
  597.  ╙┼├
  598.  ╠─╪ ╘7
  599.  ╙┬├ ╙╔╬,╪
  600.  ╙┼├
  601.  ╠─╪ ╘8
  602.  ╙┬├ ╙╔╬,╪ ;┼I=(SIN(T5)-SIN(T6)-SIN(T7)-SIN(T8))/2
  603.  >>> ─╔╓2
  604.  ├╠├
  605.  ╠─╪ ╘3
  606.  ┴─├ ├╧╙,╪
  607.  ├╠├
  608.  ╠─╪ ╘4
  609.  ┴─├ ├╧╙,╪
  610.  ╙╘┴ ┼22 ;┼=(COS(T3)+COS(T4)+┼I)/2
  611. :├┴╠├╞ ╠─╪ ╘9
  612.  ╠─┴ ╙╔╬,╪
  613.  ╙┼├
  614.  ╠─╪ ╘10
  615.  ╙┬├ ╙╔╬,╪
  616.  ╙╘┴ ╞23 ;╞=(SIN(T9)-SIN(T10))/2
  617. :├┴╠├╟ ╠─╪ ╘6
  618.  ╠─┴ ╙╔╬,╪
  619.  ╙┼├
  620.  ╠─╪ ╘8
  621.  ╙┬├ ╙╔╬,╪
  622.  ╙┼├
  623.  ╠─╪ ╘7
  624.  ╙┬├ ╙╔╬,╪
  625.  ╙┼├
  626.  ╠─╪ ╘5
  627.  ╙┬├ ╙╔╬,╪ ;╟I=(SIN(T6)-SIN(T8)-SIN(T7)-SIN(T5))/2
  628.  >>> ─╔╓2
  629.  ├╠├
  630.  ╠─╪ ╘4
  631.  ┴─├ ├╧╙,╪
  632.  ╙┼├
  633.  ╠─╪ ╘3
  634.  ╙┬├ ├╧╙,╪
  635.  ╙╘┴ ╟31 ;╟=(COS(T4)-COS(T3)+╟I)/2
  636.  >>> ─┼┬╒╟┴,╟31
  637.  >>> ─┼┬╒╟,'G'
  638. :├┴╠├╚ ├╠├
  639.  ╠─╪ ╘6
  640.  ╠─┴ ├╧╙,╪
  641.  ╠─╪ ╘7
  642.  ┴─├ ├╧╙,╪
  643.  ╙┼├
  644.  ╠─╪ ╘5
  645.  ╙┬├ ├╧╙,╪
  646.  ╙┼├
  647.  ╠─╪ ╘8
  648.  ╙┬├ ├╧╙,╪ ;╚I=(COS(T6)+COS(T7)-COS(T5)-COS(T8))/2
  649.  >>> ─╔╓2
  650.  ├╠├
  651.  ╠─╪ ╘3
  652.  ┴─├ ╙╔╬,╪
  653.  ├╠├
  654.  ╠─╪ ╘4
  655.  ┴─├ ╙╔╬,╪
  656.  ╙╘┴ ╚32 ;╚=(SIN(T3)+SIN(T4)+╚I)/2
  657. :╫╚┼╫ ├╠├
  658.  ╠─╪ ╘9
  659.  ╠─┴ ├╧╙,╪
  660.  ╠─╪ ╘10
  661.  ┴─├ ├╧╙,╪
  662.  ╙╘┴ ╔33 ;╔=(COS(T9)+COS(T10))/2
  663.  
  664. **.╔T'S.ALL.DOWNHILL.FROM.HERE.
  665.  
  666. **.╥OTATE,.PROJECT,.AND.STORE.THE.POINTS
  667. ─╧╫╬╚╔╠╠ ╠─┴ ┴11 ;╘HIS.IS.GETTING.TO.BE.A.REAL.MESS
  668.  ╙╘┴ ╘┴
  669.  ╠─┴ ┬12 ;╘HE.REASON.THIS.IS.DONE
  670.  ╙╘┴ ╘┬ ;IS.TO.MAKE.THE.CODE.A.LITTLE
  671.  ╠─┴ ├13 ;EASIER.TO.READ.(AND.DEBUG!)
  672.  ╙╘┴ ╘├
  673.  ╠─┴ ─21 ;╘HESE.ARE.ALL.TEMPORARY.LOCATIONS
  674.  ╙╘┴ ╘─ ;╒SED.BY.THE.PROJECTION.SUBROUTINE.
  675.  ╠─┴ ┼22
  676.  ╙╘┴ ╘┼ ;╧THERWISE,.THERE.WOULD.BE.EIGHT
  677.  ╠─┴ ╞23 ;LONG.ROUTINES.HERE.
  678.  ╙╘┴ ╘╞
  679.  ╠─┴ ╟31 ;┬UT.IT.WOULD.BE.SIGNIFICANTLY.FASTER
  680.  ╙╘┴ ╘╟
  681.  ╠─┴ ╚32
  682.  ╙╘┴ ╘╚
  683.  ╠─┴ ╔33
  684.  ╙╘┴ ╘╔
  685.  
  686. *.┴.NEAT.MACRO
  687. ╬┼╟ ═┴├  ;├HANGE.THE.SIGN.OF.A.TWO'S.COMPLEMENT
  688.  ├╠├
  689.  ╠─┴ ]1 ;NUMBER.
  690.  ┼╧╥ #$╞╞
  691.  ┴─├ #$01
  692.  <<<
  693.  
  694. *.╨1=[1.1.1]
  695.  ╩╙╥ ╨╥╧╩┼├╘ ;╒NROLL.THIS.WHOLE.THING
  696.  ╠─╪ ╘╪1 ;(SORRY.ABOUT.THESE.TWO.LINES)
  697.  ╠─┘ ╘┘1 ;(SEE.╨╥╧╩┼├╘.FOR.REASON.WHY)
  698.  ╙╘╪ ╨1╪ ;╞OR.A.PRETTY.BIG.SPEED.INCREASE!
  699.  ╙╘┘ ╨1┘
  700. *.╨2=[1.-1.1]
  701.  >>> ╬┼╟,┬12 ;├HANGE.THESE.ELEMENTS
  702.  ╙╘┴ ╘┬
  703.  >>> ╬┼╟,┼22 ;╙INCE.Y.IS.NOW.-1
  704.  ╙╘┴ ╘┼
  705.  >>> ╬┼╟,╚32
  706.  ╙╘┴ ╘╚
  707.  ╩╙╥ ╨╥╧╩┼├╘
  708.  ╠─╪ ╘╪1
  709.  ╠─┘ ╘┘1
  710.  ╙╘╪ ╨2╪
  711.  ╙╘┘ ╨2┘
  712. *.╨3=[-1.-1.1]
  713.  >>> ╬┼╟,┴11
  714.  ╙╘┴ ╘┴
  715.  >>> ╬┼╟,─21
  716.  ╙╘┴ ╘─
  717.  >>> ╬┼╟,╟31
  718.  ╙╘┴ ╘╟
  719.  ╩╙╥ ╨╥╧╩┼├╘
  720.  ╠─╪ ╘╪1
  721.  ╠─┘ ╘┘1
  722.  ╙╘╪ ╨3╪
  723.  ╙╘┘ ╨3┘
  724. *.╨4=[-1.1.1]
  725.  ╠─┴ ┬12
  726.  ╙╘┴ ╘┬
  727.  ╠─┴ ┼22
  728.  ╙╘┴ ╘┼
  729.  ╠─┴ ╚32
  730.  ╙╘┴ ╘╚
  731.  ╩╙╥ ╨╥╧╩┼├╘
  732.  ╠─╪ ╘╪1
  733.  ╠─┘ ╘┘1
  734.  ╙╘╪ ╨4╪
  735.  ╙╘┘ ╨4┘
  736. *.╨8=[-1.1.-1]
  737.  >>> ╬┼╟,├13
  738.  ╙╘┴ ╘├
  739.  >>> ╬┼╟,╞23
  740.  ╙╘┴ ╘╞
  741.  >>> ╬┼╟,╔33
  742.  ╙╘┴ ╘╔
  743.  ╩╙╥ ╨╥╧╩┼├╘
  744.  ╠─╪ ╘╪1
  745.  ╠─┘ ╘┘1
  746.  ╙╘╪ ╨8╪
  747.  ╙╘┘ ╨8┘
  748. *.╨7=[-1.-1.-1]
  749.  >>> ╬┼╟,┬12
  750.  ╙╘┴ ╘┬
  751.  >>> ╬┼╟,┼22
  752.  ╙╘┴ ╘┼
  753.  >>> ╬┼╟,╚32
  754.  ╙╘┴ ╘╚
  755.  ╩╙╥ ╨╥╧╩┼├╘
  756.  ╠─╪ ╘╪1
  757.  ╠─┘ ╘┘1
  758.  ╙╘╪ ╨7╪
  759.  ╙╘┘ ╨7┘
  760. *.╨6=[1.-1.-1]
  761.  ╠─┴ ┴11
  762.  ╙╘┴ ╘┴
  763.  ╠─┴ ─21
  764.  ╙╘┴ ╘─
  765.  ╠─┴ ╟31
  766.  ╙╘┴ ╘╟
  767.  ╩╙╥ ╨╥╧╩┼├╘
  768.  ╠─╪ ╘╪1
  769.  ╠─┘ ╘┘1
  770.  ╙╘╪ ╨6╪
  771.  ╙╘┘ ╨6┘
  772. *.╨5=[1.1.-1]
  773.  ╠─┴ ┬12
  774.  ╙╘┴ ╘┬
  775.  ╠─┴ ┼22
  776.  ╙╘┴ ╘┼
  777.  ╠─┴ ╚32
  778.  ╙╘┴ ╘╚
  779.  ╩╙╥ ╨╥╧╩┼├╘
  780.  ╠─╪ ╘╪1
  781.  ╠─┘ ╘┘1
  782.  ╙╘╪ ╨5╪
  783.  ╙╘┘ ╨5┘
  784.  
  785. ****.├LEAR.BUFFER
  786.  
  787.  >>> ╙┼╘┬╒╞
  788. ├╠╥┬╒╞ ╠─┴ #$00 ;╨RETTY.STRAIGHTFORWARD,
  789.  ╠─╪ #$08 ;╔.THINK
  790.  ╠─┘ #$00
  791. :╠╧╧╨ ╙╘┴ (┬╒╞╞┼╥),┘
  792.  ╔╬┘
  793.  ┬╬┼ :╠╧╧╨
  794.  ╔╬├ ┬╒╞╞┼╥+1
  795.  ─┼╪
  796.  ┬╬┼ :╠╧╧╨
  797.  ╠─┴ ┬╒╞╞┼╥+1
  798.  
  799. ****.╞INALLY,.DRAW.THE.LINES.
  800.  
  801.  ╠─┴ ╨1╪ ;[1.1.1]
  802.  ╙╘┴ ╘╪1
  803.  ╠─┴ ╨1┘
  804.  ╙╘┴ ╘┘1
  805.  ╠─┴ ╨2╪ ;[1.-1.1]
  806.  ╙╘┴ ╘╪2
  807.  ╠─┴ ╨2┘
  808.  ╙╘┴ ╘┘2
  809.  ╩╙╥ ─╥┴╫ ;╞IRST.LINE
  810.  
  811.  ╠─┴ ╨3╪ ;[-1.-1.1]
  812.  ╙╘┴ ╘╪1
  813.  ╠─┴ ╨3┘
  814.  ╙╘┴ ╘┘1
  815.  ╩╙╥ ─╥┴╫ ;╙ECOND.LINE
  816.  
  817.  ╠─┴ ╨4╪ ;[-1.1.1]
  818.  ╙╘┴ ╘╪2
  819.  ╠─┴ ╨4┘
  820.  ╙╘┴ ╘┘2
  821.  ╩╙╥ ─╥┴╫ ;╘HIRD.LINE
  822.  
  823.  ╠─┴ ╨1╪ ;[1.1.1]
  824.  ╙╘┴ ╘╪1
  825.  ╠─┴ ╨1┘
  826.  ╙╘┴ ╘┘1
  827.  ╩╙╥ ─╥┴╫ ;╞OURTH.LINE...╧NE.FACE.DONE.
  828.  
  829.  ╠─┴ ╨5╪ ;[1.1.-1]
  830.  ╙╘┴ ╘╪2
  831.  ╠─┴ ╨5┘
  832.  ╙╘┴ ╘┘2
  833.  ╩╙╥ ─╥┴╫ ;╞IVE
  834.  
  835.  ╠─┴ ╨6╪ ;[1.-1.-1]
  836.  ╙╘┴ ╘╪1
  837.  ╠─┴ ╨6┘
  838.  ╙╘┴ ╘┘1
  839.  ╩╙╥ ─╥┴╫ ;╙IX
  840.  
  841.  ╠─┴ ╨2╪ ;[1.-1.1]
  842.  ╙╘┴ ╘╪2
  843.  ╠─┴ ╨2┘
  844.  ╙╘┴ ╘┘2
  845.  ╩╙╥ ─╥┴╫ ;╙EVEN
  846.  
  847.  ╠─┴ ╨7╪ ;[-1.-1.-1]
  848.  ╙╘┴ ╘╪2
  849.  ╠─┴ ╨7┘
  850.  ╙╘┴ ╘┘2
  851.  ╩╙╥ ─╥┴╫ ;┼IGHT
  852.  
  853.  ╠─┴ ╨3╪ ;[-1.-1.1]
  854.  ╙╘┴ ╘╪1
  855.  ╠─┴ ╨3┘
  856.  ╙╘┴ ╘┘1
  857.  ╩╙╥ ─╥┴╫ ;╬INE
  858.  
  859.  ╠─┴ ╨8╪ ;[-1.1.-1]
  860.  ╙╘┴ ╘╪1
  861.  ╠─┴ ╨8┘
  862.  ╙╘┴ ╘┘1
  863.  ╩╙╥ ─╥┴╫ ;╘EN
  864.  
  865.  ╠─┴ ╨4╪ ;[-1.1.1]
  866.  ╙╘┴ ╘╪2
  867.  ╠─┴ ╨4┘
  868.  ╙╘┴ ╘┘2
  869.  ╩╙╥ ─╥┴╫ ;┼LEVEN
  870.  
  871.  ╠─┴ ╨5╪ ;[1.1.-1]
  872.  ╙╘┴ ╘╪2
  873.  ╠─┴ ╨5┘
  874.  ╙╘┴ ╘┘2
  875.  ╩╙╥ ─╥┴╫ ;╘WELVE!
  876.  
  877. ****.╙WAP.BUFFERS
  878.  
  879. ╙╫┴╨┬╒╞ ╠─┴ ╓═├╙┬
  880.  ┼╧╥ #$02 ;╨RETTY.TRICKY,.EH?
  881.  ╙╘┴ ╓═├╙┬
  882.  ╠─┴ #$08
  883.  ┼╧╥ ┌╘┼═╨ ;ZTEMP=HIGH.BYTE.JUST.FLIPS
  884.  ╙╘┴ ┌╘┼═╨ ;BETWEEN.$30.AND.$38
  885.  
  886.  ╩═╨ ═┴╔╬ ;┴ROUND.AND.AROUND.WE.GO...
  887.  
  888.  
  889. *-------------------------------
  890. *.╘HIS.SUBROUTINE.CALCULATES.THE.PROJECTION.OF.╪.AND.┘
  891.  
  892. ╨╥╧╩┼├╘ ├╠├
  893.  ╠─┴ ╘╟
  894.  ┴─├ ╘╚
  895.  ├╠├
  896.  ┴─├ ╘╔ ;╘HIS.IS.ROTATED.┌
  897.  ├╠├
  898.  ┴─├ #128 ;╫E.ARE.GOING.TO.TAKE.128+Z
  899.  ╘┴╪  ;╬OW.IT.IS.READY.FOR.INDEXING
  900.  ╠─┴ ┌─╔╓,╪ ;╘ABLE.OF.-D/Z
  901.  ╙╘┴ ┴╒╪ ;╘HIS.IS.FOR.THE.PROJECTION
  902.  ╙╘┴ ╥┼═ ;═ULTIPLY.CAN.CLOBBER.┴╒╪
  903.  
  904.  ├╠├
  905.  ╠─┴ ╘┴
  906.  ┴─├ ╘┬
  907.  ├╠├
  908.  ┴─├ ╘├
  909.  ╙╘┴ ┴├├ ;╘HIS.IS.ROTATED.X
  910.  ╩╙╥ ╙═╒╠╘ ;╙IGNED.MULTIPLY.┴├├*┴╒╪/2^╧╞╞╙┼╘
  911.  ├╠├
  912.  ╠─┴ ┴├├
  913. :├╧╬╘1 ┴─├ #64 ;╧FFSET.THE.COORDINATE
  914. *.╙EE.BELOW.FOR.THE.REASON.WHY.THIS
  915. *.NEXT.INSTRUCTION.IS.COMMENTED.OUT
  916. *.╘┴╪..;╬OW.╪.IS.X!
  917.  ╙╘┴ ╘╪1
  918.  ├╠├  ;─O.THE.WHOLE.THING.AGAIN.FOR.┘
  919.  ╠─┴ ╥┼═
  920.  ╙╘┴ ┴╒╪
  921.  ╠─┴ ╘─
  922.  ┴─├ ╘┼
  923.  ├╠├
  924.  ┴─├ ╘╞
  925.  ╙╘┴ ┴├├ ;╘HIS.IS.ROTATED.Y
  926.  ╩╙╥ ╙═╒╠╘ ;╙IGNED.MULTIPLY.┴├├*┴╒╪/2^╧╞╞╙┼╘
  927.  ├╠├
  928.  ╠─┴ ┴├├
  929. :├╧╬╘2 ┴─├ #64 ;╧FFSET.THE.COORDINATE
  930. *.╞OR.SOME.COMPLETELY.UNKNOWN.REASON.TO.ME
  931. *.THE.INSTRUCTION.BELOW.DOESN'T.WORK...╙OMEHOW
  932. *.THE.╥╘╙.IS.MODIFYING.╪.AND.┘???
  933. *.╘┴┘..;╙TORE.IN.┘
  934.  ╙╘┴ ╘┘1
  935.  ╥╘╙  ;╔.HOPE.TO.HECK.THIS.WORKS.
  936.  
  937. *-------------------------------
  938. *.╙═╒╠╘:.8-BIT.SIGNED.(SORT-OF).MULTIPLY
  939. *
  940. *.┴├├*┴╒╪/2^╧╞╞╙┼╘.->.[┴├├,.┼╪╘]..16-BIT.RESULT..LO,HI
  941. *
  942. *.╬OTE.THAT.THIS.ROUTINE.DIVIDES.THE.END.RESULT.BY.2^╧╞╞╙┼╘
  943.  
  944. *.┘UP,.ANOTHER.MACRO.
  945. ─╔╓╧╞╞ ═┴├  ;─IVIDE.BY.THE.FLOAT.OFFSET
  946.  ╠╒╨ ╧╞╞╙┼╘ ;╥EPEAT.OFFSET.TIMES
  947.  ╠╙╥  ;┴.CONTAINS.HIGH.BYTE
  948.  ╥╧╥ ┴├├ ;┴├├.IS.LOW.BYTE
  949.  --^
  950.  <<<
  951.  
  952.  
  953. ╙═╒╠╘ ├╠├
  954.  ╠─┴ ┴├├ ;╞IRST,.IS.THE.RESULT.POSITIVE.OR.NEGATIVE?
  955.  ┼╧╥ ┴╒╪
  956.  ┬═╔ :╬┼╟
  957.  
  958.  ╠─┴ ┴├├ ;╘HEY.ARE.EITHER.BOTH.NEGATIVE.OR
  959.  ┬╨╠ :├╧╬╘1 ;BOTH.POSITIVE
  960.  ┼╧╥ #$╞╞ ;╔N.THIS.CASE,.MAKE.THEM
  961.  ┴─├ #$01 ;BOTH.POSITIVE!
  962.  ╙╘┴ ┴├├
  963.  >>> ╬┼╟,┴╒╪ ;╠ITTLE.MACRO.USED.EARLIER.
  964. :├╧╬╘1 ╠─┴ #00 ;═ULTIPLY.THE.TWO.NUMBERS
  965.  ╠─┘ #$09
  966. ]╠╧╧╨ ╠╙╥  ;╥EAD.THE.ARTICLE.FOR.DETAILS.
  967.  ╥╧╥ ┴├├
  968.  ┬├├ :═╒╠╘1 ;╧R.FIGURE.IT.OUT.YOURSELF!
  969.  ├╠├
  970.  ┴─├ ┴╒╪
  971. :═╒╠╘1 ─┼┘
  972.  ┬╬┼ ]╠╧╧╨
  973.  >>> ─╔╓╧╞╞ ;╥EMOVE.THIS.LINE.FOR.A.GENERAL.MULTIPLY
  974.  ╙╘┴ ┼╪╘
  975.  ╥╘╙
  976.  
  977. :╬┼╟ ╠─┴ ┴├├ ;╧NE.OF.THE.TWO.IS.NEGATIVE
  978.  ┬═╔ :├╧╬╘2
  979.  >>> ╬┼╟,┴╒╪ ;╧THERWISE.IT'S.┴╒╪
  980.  ╩═╨ :├╧╬╘3
  981. :├╧╬╘2 ┼╧╥ #$╞╞ ;╘AKE.TWO'S.COMPLEMENT
  982.  ┴─├ #$01
  983.  ╙╘┴ ┴├├
  984. :├╧╬╘3 ╠─┴ #00 ;═ULTIPLY
  985.  ╠─┘ #$09
  986. ]╠╧╧╨2 ╠╙╥
  987.  ╥╧╥ ┴├├
  988.  ┬├├ :═╒╠╘2
  989.  ├╠├
  990.  ┴─├ ┴╒╪
  991. :═╒╠╘2 ─┼┘
  992.  ┬╬┼ ]╠╧╧╨2
  993.  >>> ─╔╓╧╞╞ ;┴GAIN,.DIVIDE.BY.THE.OFFSET
  994.  ╙╘┴ ┼╪╘
  995.  ╠─┴ ┴├├
  996.  ┬╨╠ :╧╦ ;╙OMETHING.IS.REALLY.WRONG.IF.THIS.IS.NEGATIVE.
  997.  ╩╙╥ ├╚╧╦┼
  998. :╧╦ ┼╧╥ #$╞╞ ;╧THERISE,.EVERYTHING.RELEVANT.SHOULD
  999.  ┴─├ #$01 ;BE.COMPLETELY.IN.THE.LOW.BYTE.
  1000.  ╙╘┴ ┴├├
  1001.  ╥╘╙  ;╔.HOPE...
  1002.  
  1003. *-------------------------------
  1004. *.╟ENERAL.QUESTIONABLE-VALUE.ERROR.PROCEDURE
  1005.  
  1006. ├╚╧╦┼ ╠─╪ #00
  1007. :╠╧╧╨ ╠─┴ :├╘┼╪╘,╪
  1008.  ┬┼╤ :─╧╬┼
  1009.  ╩╙╥ ├╚╥╧╒╘
  1010.  ╔╬╪
  1011.  ╩═╨ :╠╧╧╨
  1012. :─╧╬┼ ╥╘╙
  1013. :├╘┼╪╘ ╚┼╪ 0─ ;├╥
  1014.  ╘╪╘ 'SOMETHING.CHOKED.:('
  1015.  ╚┼╪ 0─00
  1016.  
  1017. *-------------------------------
  1018. *.─RAWIN'.A.LINE...┴.FAHN.LAHN.
  1019.  
  1020. ***.╙OME.USEFUL.MACROS
  1021.  
  1022. ╨╠╧╘╨╪ ═┴├  ;PLOT.A.POINT.IN.X
  1023.  ╨╚┴  ;╒SE.THIS.ONE.EVERY.TIME
  1024.  ╠─┴ ┬╔╘╨,╪ ;╪.IS.INCREASED
  1025.  ┬╨╠ ├1
  1026.  ┼╧╥ ┬╒╞╞┼╥
  1027.  ╙╘┴ ┬╒╞╞┼╥
  1028.  ┬═╔ ├2
  1029.  ╔╬├ ┬╒╞╞┼╥+1
  1030. ├2 ╠─┴ #%10000000
  1031. ├1 ╧╥┴ (┬╒╞╞┼╥),┘
  1032.  ╙╘┴ (┬╒╞╞┼╥),┘
  1033.  ╨╠┴  ;╬EED.TO.SAVE.┴!
  1034.  <<<
  1035.  
  1036. ╨╠╧╘╨┘ ═┴├  ;╨LOT.A.POINT.IN.Y:.SIMPLER.AND.NECESSARY!
  1037.  ╨╚┴  ;╒SE.THIS.ONE.WHEN.YOU.JUST.INCREASE.┘
  1038.  ╠─┴ ┬╔╘╨,╪ ;BUT.╪.DOESN'T.CHANGE
  1039.  ╧╥┴ (┬╒╞╞┼╥),┘
  1040.  ╙╘┴ (┬╒╞╞┼╥),┘
  1041.  ╨╠┴
  1042.  <<<
  1043.  
  1044. ├╔╬╔╘ ═┴├  ;═ACRO.TO.INITIALIZE.THE.COUNTER
  1045.  ╠─┴ ]1 ;DX.OR.DY
  1046.  ╠╙╥
  1047.  ┼╧╥ #$╞╞ ;(╬OT.REALLY.TWO'S.COMPLEMENT)
  1048.  ┴─├ #$01 ;┴.=.256-DX/2.OR.256-DY/2
  1049.  <<<  ;╘HE.DX/2.MAKES.A.NICER.LOOKING.LINE
  1050.  
  1051. ╪╙╘┼╨ ═┴├  ;═ACRO.TO.TAKE.A.STEP.IN.╪
  1052. ╪╠╧╧╨ ╔╬╪
  1053.  ┴─├ ─┘
  1054.  ┬├├ ╠1
  1055. *.─O.WE.USE.╔╬┘.OR.─┼┘.HERE?
  1056.  ╔╞ ╔,]1 ;╔F.THE.FIRST.CHARACTER.IS.AN.'╔'
  1057.  ╔╬┘
  1058.  ┼╠╙┼
  1059.  ─┼┘
  1060.  ╞╔╬
  1061.  ╙┬├ ─╪
  1062. ╠1 >>> ╨╠╧╘╨╪ ;┴LWAYS.TAKE.A.STEP.IN.╪
  1063.  ├╨╪ ╪2
  1064.  ┬╬┼ ╪╠╧╧╨
  1065.  <<<
  1066.  
  1067. ┘╙╘┼╨ ═┴├  ;╙AME.THING,.BUT.FOR.┘
  1068. ┘╠╧╧╨ ╔╞ ╔,]1
  1069.  ╔╬┘
  1070.  ┼╠╙┼
  1071.  ─┼┘
  1072.  ├╠├  ;╓ERY.IMPORTANT!
  1073.  ╞╔╬
  1074.  ┴─├ ─╪
  1075.  ┬├├ ╠2
  1076.  ╔╬╪  ;┴LWAYS.INCREASE.╪
  1077.  ╙┬├ ─┘
  1078.  >>> ╨╠╧╘╨╪
  1079.  ╩═╨ ╠3
  1080. ╠2 >>> ╨╠╧╘╨┘ ;╫E.ONLY.INCREASED.┘
  1081. ╠3 ├╨┘ ┘2
  1082.  ┬╬┼ ┘╠╧╧╨
  1083.  <<<
  1084.  
  1085. ****.╔NITIAL.LINE.SETUP
  1086.  
  1087. ─╥┴╫ >>> ═╧╓┼,╘╪1;╪1  ;═OVE.STUFF.INTO.ZERO.PAGE
  1088.  >>> ═╧╓┼,╘╪2;╪2  ;╫HERE.IT.CAN.BE.MODIFIED
  1089.  >>> ═╧╓┼,╘┘1;┘1
  1090.  >>> ═╧╓┼,╘┘2;┘2
  1091.  >>> ╙┼╘┬╒╞ ;╬OW.WE.CAN.CLOBBER.THE.BUFFER
  1092.  
  1093.  ╙┼├  ;═AKE.SURE.X1<X2
  1094.  ╠─┴ ╪2
  1095.  ╙┬├ ╪1
  1096.  ┬├╙ :├╧╬╘
  1097.  ╠─┴ ┘2 ;╔F.NOT,.SWAP.╨1.AND.╨2
  1098.  ╠─┘ ┘1
  1099.  ╙╘┴ ┘1
  1100.  ╙╘┘ ┘2
  1101.  ╠─┴ ╪1
  1102.  ╠─┘ ╪2
  1103.  ╙╘┘ ╪1
  1104.  ╙╘┴ ╪2
  1105.  
  1106.  ╙┬├ ╪1 ;╬OW.┴=DX
  1107. :├╧╬╘ ╙╘┴ ─╪
  1108.  ╠─╪ ╪1 ;╨UT.X1.INTO.╪,.NOW.WE.CAN.TRASH.╪1
  1109.  
  1110. ├╧╠╒═╬ ╠─┴ ╪1 ;╞IND.THE.FIRST.COLUMN.FOR.╪
  1111.  ╠╙╥  ;(╘HIS.CAN.BE.MADE.MUCH.FASTER!)
  1112.  ╠╙╥  ;╘HERE.ARE.X1/8.128.BYTE.BLOCKS
  1113.  ╠╙╥  ;╫HICH.MEANS.X1/16.256.BYTE.BLOCKS
  1114.  ╠╙╥
  1115.  ┬├├ :┼╓┼╬ ;╫ITH.A.POSSIBLE.EXTRA.128.BYTE.BLOCK
  1116.  ╠─┘ #$80 ;IF.SO,.SET.THE.HIGH.BIT
  1117.  ╙╘┘ ┬╒╞╞┼╥
  1118.  ├╠├
  1119. :┼╓┼╬ ┴─├ ┬╒╞╞┼╥+1 ;┴DD.IN.THE.NUMBER.OF.256.BYTE.BLOCKS
  1120.  ╙╘┴ ┬╒╞╞┼╥+1 ;┴ND.STORE.IT!
  1121.  
  1122.  ╙┼├
  1123.  ╠─┴ ┘2 ;├ALCULATE.DY
  1124.  ╙┬├ ┘1
  1125.  ┬├╙ :├╧╬╘2 ;╔S.Y2>Y1?
  1126.  ╠─┴ ┘1 ;╧THERWISE.DY=Y1-Y2
  1127.  ╙┬├ ┘2
  1128. :├╧╬╘2 ╙╘┴ ─┘
  1129.  ├═╨ ─╪ ;╫HO'S.BIGGER:.DY.OR.DX?
  1130.  ┬├╙ ╙╘┼╨╔╬┘ ;╔F.DY,.WE.NEED.TO.TAKE.BIG.STEPS.IN.Y
  1131.  
  1132. ╙╘┼╨╔╬╪ ╠─┘ ┘1 ;╪.IS.ALREADY.SET.TO.X1
  1133.  ╠─┴ ┬╔╘╨,╪ ;╨LOT.THE.FIRST.POINT
  1134.  ╧╥┴ (┬╒╞╞┼╥),┘
  1135.  ╙╘┴ (┬╒╞╞┼╥),┘
  1136.  >>> ├╔╬╔╘,─╪ ;╔NITIALIZE.THE.COUNTER
  1137.  ├╨┘ ┘2
  1138.  ┬├╙ ╪─┼├┘ ;─O.WE.STEP.FORWARDS.OR.BACKWARDS.IN.┘?
  1139.  
  1140. ╪╔╬├┘ >>> ╪╙╘┼╨,╔╬┘
  1141.  ╥╘╙
  1142.  
  1143. ╪─┼├┘ >>> ╪╙╘┼╨,─┼┘
  1144.  ╥╘╙
  1145.  
  1146. ╙╘┼╨╔╬┘ ╠─┘ ┘1 ;╫ELL,.A.LITTLE.REPETITION.NEVER.HURT.ANYONE
  1147.  ╠─┴ ┬╔╘╨,╪
  1148.  ╧╥┴ (┬╒╞╞┼╥),┘
  1149.  ╙╘┴ (┬╒╞╞┼╥),┘
  1150.  >>> ├╔╬╔╘,─┘
  1151.  ├╨┘ ┘2
  1152.  ┬├╙ ┘─┼├┘
  1153.  
  1154. ┘╔╬├┘ >>> ┘╙╘┼╨,╔╬┘
  1155.  ╥╘╙
  1156.  
  1157. ┘─┼├┘ >>> ┘╙╘┼╨,─┼┘
  1158.  ╥╘╙
  1159.  
  1160.  
  1161. *-------------------------------
  1162. *.├LEAN.UP
  1163.  
  1164. ├╠┼┴╬╒╨ ╠─┴ ╓═├╙┬ ;╙WITCH.CHAR.ROM.BACK.IN
  1165.  ┴╬─ #%11110101 ;DEFAULT
  1166.  ╙╘┴ ╓═├╙┬
  1167.  
  1168.  ╥╘╙  ;BYE!
  1169.  
  1170. *-------------------------------
  1171. *.╙OME.VARIABLES
  1172.  
  1173. ╘╪1 ─╙ 1
  1174. ╘┘1 ─╙ 1
  1175. ╘╪2 ─╙ 1
  1176. ╘┘2 ─╙ 1
  1177. ╨1╪ ─╙ 1 ;╘HESE.ARE.TEMPORARY.STORAGE
  1178. ╨1┘ ─╙ 1 ;╒SED.IN.PLOTTING.THE.PROJECTION
  1179. ╨2╪ ─╙ 1
  1180. ╨2┘ ─╙ 1 ;╘HEY.ARE.HERE.SO.THAT.WE
  1181. ╨3╪ ─╙ 1 ;DON'T.HAVE.TO.RECALCULATE.THEM.
  1182. ╨3┘ ─╙ 1
  1183. ╨4╪ ─╙ 1 ;╘HEY.MAKE.LIFE.EASY.
  1184. ╨4┘ ─╙ 1
  1185. ╨5╪ ─╙ 1 ;╫HY.ARE.YOU.LOOKING.AT.ME.LIKE.THAT?
  1186. ╨5┘ ─╙ 1 ;─ON'T.YOU.TRUST.ME?
  1187. ╨6╪ ─╙ 1
  1188. ╨6┘ ─╙ 1 ;╚AVING.ANOTHER.CHILD.WASN'T.MY.IDEA.
  1189. ╨7╪ ─╙ 1
  1190. ╨7┘ ─╙ 1
  1191. ╨8╪ ─╙ 1
  1192. ╨8┘ ─╙ 1
  1193. ─╙╪ ─╙ 1 ;─╙╪.IS.THE.INCREMENT.FOR.ROTATING.AROUND.X
  1194. ─╙┘ ─╙ 1 ;╙IMILAR.FOR.─╙┘,.─╙┌
  1195. ─╙┌ ─╙ 1
  1196. ╙╪ ─╙ 1 ;╘HESE.ARE.THE.ACTUAL.ANGLES.IN.X.Y.AND.Z
  1197. ╙┘ ─╙ 1
  1198. ╙┌ ─╙ 1
  1199. ╘1 ─╙ 1 ;╘HESE.ARE.USED.IN.THE.ROTATION
  1200. ╘2 ─╙ 1
  1201. ╘3 ─╙ 1 ;╙EE.THE.ARTICLE.FOR.MORE.DETAILS
  1202. ╘4 ─╙ 1
  1203. ╘5 ─╙ 1
  1204. ╘6 ─╙ 1
  1205. ╘7 ─╙ 1
  1206. ╘8 ─╙ 1
  1207. ╘9 ─╙ 1
  1208. ╘10 ─╙ 1
  1209. ┴11 ─╙ 1 ;╘HESE.ARE.THE.ELEMENTS.OF.THE.ROTATION.MATRIX
  1210. ┬12 ─╙ 1 ;╪┘┌
  1211. ├13 ─╙ 1
  1212. ─21 ─╙ 1 ;╘HE.NUMBER.DENOTES.(ROW,COLUMN)
  1213. ┼22 ─╙ 1
  1214. ╞23 ─╙ 1
  1215. ╟31 ─╙ 1
  1216. ╚32 ─╙ 1
  1217. ╔33 ─╙ 1
  1218. ╘┴ ─╙ 1 ;╘HESE.ARE.TEMPORARY.LOCATIONS
  1219. ╘┬ ─╙ 1 ;FOR.USE.BY.THE.PROJECTION.ROUTINE
  1220. ╘├ ─╙ 1
  1221. ╘─ ─╙ 1
  1222. ╘┼ ─╙ 1
  1223. ╘╞ ─╙ 1
  1224. ╘╟ ─╙ 1
  1225. ╘╚ ─╙ 1
  1226. ╘╔ ─╙ 1
  1227.  
  1228. *-------------------------------
  1229. *.╙ET.UP.BIT.TABLE
  1230.  
  1231.  ─╙ ^ ;├LEAR.TO.END.OF.PAGE
  1232.    ;╙O.THAT.TABLES.START.ON.A.PAGE.BOUNDARY
  1233. ┬╔╘╨ ╠╒╨ 16 ;128.┼NTRIES.FOR.╪
  1234.  ─╞┬ %10000000
  1235.  ─╞┬ %01000000
  1236.  ─╞┬ %00100000
  1237.  ─╞┬ %00010000
  1238.  ─╞┬ %00001000
  1239.  ─╞┬ %00000100
  1240.  ─╞┬ %00000010
  1241.  ─╞┬ %00000001
  1242.  --^
  1243. ╙╔╬   ;╘ABLE.OF.SINES,.120.BYTES
  1244. ├╧╙ ┼╤╒ ╙╔╬+128 ;╘ABLE.OF.COSINES
  1245.    ;┬OTH.OF.THESE.TRIG.TABLES.ARE
  1246.    ;CURRENTLY.SET.UP.FROM.┬┴╙╔├
  1247. ┌─╔╓ ┼╤╒ ├╧╙+128 ;─IVISION.TABLE
  1248.  
  1249. ╒╒ENCODED ┬INARIES
  1250. ------------------
  1251. BEGIN 666 RUNME3D
  1252. ═ 0@>" ╚ ┬╘&╥,*=!╠├$┌─╥)#54)%,╘0╬3╥(╠."╨┘ "╪(% "3(─┼.250╙1"(╠
  1253. ═.    !╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:
  1254. ╞&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:
  1255.  
  1256. END
  1257.  
  1258. BEGIN 666 INIT3D
  1259. ═ 0@─" ╚ ├╥!04─]'4─%-(%1/($┼.251)04╤)6─4@0╒5"13-$ $8(% "/(%-4
  1260. ═15!(14╪@2┼5$1"╨@1╘5/4─=%(%1!64╤/4@!7"!─ ╞2(%5╘]22╘┼.1╥([ ',(
  1261. ═'@!"4[(╓-3(╪.─)#╠├8╓-38┌0┼╩╥-├<╪- "#""@ 0;(╨.─1!╠╧^═-├  ╠╨@╥
  1262. ═ (%)╠├"─,3(╨.┼,┼╠├,╥╦+\╚02╞╩+├4┌0╥6╥,╙*╠╧┬┴!*:╚╬-3╔!╠─&╩1$$ 
  1263. ═╧0@╙ )─┬+┬([ -0(-╨"+(%,┼╠╙ @╔╥!3);(╥-3:╩4╥4 ┌╨@╪ (╠@0╥6╙,""╟
  1264. ═($,┼╠├(╒-╩╔#)0 !"3╚ ┼╘)3╩──╠4╥4┌┼╘)#╩──╠0╥4 !╨─[ (( (0─\ $2╥
  1265. ═.# ┌6├"╥,╙╔:╠╩╠╤,├@┌1%╩╥,0 ╬"48 @4╩╥,*0╥-34 . ┼' )─┬(2([ $╪)
  1266. ═4 !1);(╓-*╤$╦2@╓-*╤:,*═:*0!─"5$ ┬╥!1);$╤,├<@╔╥!1);(╤,├< ? ┼2
  1267. ═ (╠@426╙╩╙$╥-╥"╟(%$┼╠╩╠╤,├< ─╨┼3 (╠@426╙,""╟(%$┼╠├(╒-╩╔1)0"@
  1268. ═"54 ┼╘):╩─╚╠424 ╦0┼: %╩╥6╩╔$6├╩" ,4)9 ">-# ┘-├╩9(─┘%050╠($┴5
  1269. ═2#\┬    &┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:
  1270. 1&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:
  1271.  
  1272. END
  1273.  
  1274. BEGIN 666 LISTME3D
  1275. ═ 0@8" ╚ ├╥!.3╒1%4╥!&3╒(@0╒5"13-$ !╪("╨"/ $4(# "/(%1(15)%($%2
  1276. ═12!35$┼,3"!!($9%5╥!-24┘/4┬!"54=3 &─(#0"/(%1(12!-3╒1)3╘╪@25,@
  1277. ═2─522╒─@1─]2(%--04╤, (╘(#@"/($┼.0╒)%345.5%,┌(%!23╘)!0─╤9(%)/
  1278. ═54┘$3╘9& ),(#╨"/ +@($ "/($9%14╨@1┼)%12!43╥!-3╘1)1┼─@5$┴%(%!!
  1279. ═4─╒3+@#>"!$ ├╥!*55-4(%%5250@5$┴%(%!23╘=204╘@04┘$($╤)4╒0╬  ,)
  1280. ═$@"/(%1262!#2$%.1╘┼.1╥!$($%.1"!:," ╚64]5($-!3@ ├"1, ├╥!%5─5.
  1281. ═($╒!2╘4@6┬╒:,"!.14=!5$┼612─╬ $8)% "/($)%($-!4─5&54╨@04)/550@
  1282. ═4─535$%25$┼.1╥$ ;0─5 (\@248@64]5(%=!3┼0@5$\@4╘5%(%┼/55(@0╘]-
  1283. ═4%5415( ─@─6 (\@1$┼%($%.($%-05╔)3─<@1$5!5$@@2┼535"!465!% +@)
  1284. ═%╨"/("=254╪@-├ ╟+┬!!3%=!65,@4┼5.(%1(12!%3┼1)4─4 ╤╨─8 (\@4%)/
  1285. ═1╒)!32╪ ╙0─9 (\ \╨─: (\@4╘]-151)3453(%1(12!%6453($=%5"!#3╘┘&
  1286. ═55-%1  8"┴╠ ├╥!!0─]55"!42$4@4$524╒!%0╒1)5─4╠($%.1"!42$4 .╨╚<
  1287. ═ (\@0╒5"12!724╤,($╤/3╘╠@4─5!3$╤9(%=%25)$+@!?"┴╘ ├╥!*55-4($),
  1288. ═24┘+($]2(%1262!43╥!&24┘$(%1(10"#"┴╪ ├╥!224=(5"!015)34$5#5$┼6
  1289. ═12╪@($5615(@4╘5%3@"╚"┴\ ├╥!42$4@)╘-205╔9($-2051%)╙\@(%-!344@
  1290. ═241%02╪ ╬@╚@ (\@4╘╤*(#<╧,3─╧.30    :&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:
  1291. ═&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:&┴╚:
  1292. #&┴╚:
  1293.  
  1294. END
  1295.  
  1296. BEGIN 666 CUBE3D.O
  1297. ═ !"╔ (╘@╘(╘┴╘*╘8╘"─/"1"-&-"@ *─?┴?╬╔$(7\3%41─╨41$1$@(" @(" @
  1298. ═(" @(" @("!#54)%,╘0-#2 @(" @(" @(" @(" @(" @0┼─-╟╥ @("!35$50
  1299. ═2$5.($╔51$29(" @($=%3╒)'12!405┼,3╒(-#9╠@($-(14-+($]55"!42$4@
  1300. ═2┼5,62 ┘-"!)4╒-512!/1@╓6("!#/4┴!0╘═)3─>;($9/4┬!-3╒)%($1%5$%)
  1301. ═3%,┴#0╘='9╪21├$╧1├*2("╘@24┘#+╘1%0╥!8+5)/5$%424].#1╘=$─8╙+╘8╘
  1302. ═─┬ ═($┼.0╥]$14,@62╒23╒1!5$┼/3@╘='1)&-2]&-╔(@+2!)3─,╧1$5#(%╚═
  1303. ═4─]4051)3╘╪-'1╘21├>2(%)%4╘544╨╘@(%!215-3(%$@5$\@455)5 ╘-!2 @
  1304. ═(" @(%!215-3($%.62!+15─@5$\@0─5'24╪- +'[\ ╠@╘╧_(╘/;╞_$╤5$2#─
  1305. ═_\─ \/╞╔─╥#2_┌┼ :0╥%^┌─%┴?╥╔ *  ╚@ 8─?╧(:1"0^1┬┼^╓─╚┴?╬┼_&─ 
  1306. ═┴?╥@ .┬*╪!#0┘*─ ┴:.╔,(6─┴0*═&- ╔\0─.├1├0╩0"-╙╤┬-╘!┬-╘1┬-╘┴┬-
  1307. ═╘╤┬-╒!@@┘/_)┴= -╦<\8╥3╙╨8^[/&$╨╓$╠╞)╘ ╬═╙╤├╨5,[/&$╨╓$╠╞&╘ ╓═
  1308. ═╘!├)//!#[═ 83#82╥8╦0"┌╫0&/ ╘╙═ 83#82╥8?0#:╫1&,─\\"/╬╘1┴,-┴+)
  1309. ═┬] +╦=$8\!3.╘1┴,-┴+)┬- #3+$1╥5'0 ╘╥╥&!┬═╘┴┴═╙╤├)>) "┌7┬-╘┴@8
  1310. ═╦=,8;= 8╥7┬0 ╬┼╪├=,8&*╫4&&╫1&,┼╪─ +╔>(╫4&#┬═╘╤├═╒!┬╨ ╞┼╪├=48
  1311. ═&*╫3&&╫4&,┼╪─ +╔>(╫6&!┬═╘┴┴═╒!├)>) "┌7┬-╒╤@╪╦=(8[=08╠ )╔>(╫8
  1312. ═&!┬═╘┴┴═╒┴├)>) "┌7┬-╓1@╪╦=(8[=48╠ )╔>(╫:&!┬═╘┴┴═╒1├)>) "┌7┬-
  1313. ═╓╤@╪╦=88[=(8╠ )╔>(╫<&#┬═╘╤├═╘┴┬╨ ╞┼╪├=╘8&*╫2&&╫3&,┼╪─ +╔>(╫>
  1314. ═&!┬╬╒1┬] !╩╬╒┴┴] !╩-╫╤┬╬╒1┬]@!─╪╦═88_8 9├> 8╦═,8╧8 9$ ╪82?]╔
  1315. ═ 0╚82?]╔ 4╨╙$╨╩-╪1@╪╦═╨8╧0 :╦═╠8_0 :.*[9&/╘ &┴┬╬╓┴┴] !╚0#┴┴)
  1316. ═_╓─!2┴┴)_╓─!3&(32┴┬╬╒╤┴]@!─╪╦═@8_8 9├>(8.*[9&+╓ &:[:&/╓ &3┬╬
  1317. ═╓╤├]@!─╪╦═╨8_8 9$ ╪82?]╔ 4╚82?]╔ 4╥?$╘╚8╦═<8?0 :&*[8&'╘ &╚╫├
  1318. ═&*[=&+╓ &3┬╬╫┴├]@!╞-┘!┬╬╓┴┬]@!─╪╦═╨8_8 9.*[;&/╓ &3┬╬╓1├]@!─0
  1319. ═#┴┴)_╓─!2┴┴)_╓─!3.╨32┴┬╬╓!┴] !╚╪╦═<8_0 :├>48&*[:&+╘ &╩[;&'╘ 
  1320. ═&├┬╬╓1├] !╚╪╦═╨8_0 :$ ╪82?]╔ 4╚82?]╔ 4╨╔%$╚8╦═<8?8 9&*[8&'╓ 
  1321. ═&8╫╞&!┬╬╫1┬] !╩╬╫┴┴] !╩-┘╤┬═╫╤┬-┌!┬═╪!┬-┌1┬═╪1┬-┌┴┬═╪┴┬-┌╤┬═
  1322. ═╪╤┬-[!┬═┘!┬-[1┬═┘1┬-[┴┬═┘┴┬-[╤┬═┘╤┬-\!@@╟1:╬╬╤┬╠╧!┬.╧╤┬,╨!@8
  1323. ═╦> 82?]╔ 8╫╔&!┬═╪╤┴)_╓─!├>╨8&*╫╞&$╟_:0&-[╤@@╟1:╬╬╤┬╠╧!┬.╨1┬,
  1324. ═╨┴@8╦=\82?]╔ 8╫╚&!┬═╪┴┴)_╓─!├>╠8&*╫┼&$╟_:0&-[┴@@╟1:╬╬╤┬╠╧!┬.
  1325. ═╨╤┬,╤!┬═╪!┬-┌1┬═╪╤┬-[!┬═┘┴┬-[╤@@╟1:╬╬╤┬╠╧!┬.╤1┬,╤┴@8╦>$82?]╔
  1326. ═ 8╫╩&!┬═┘!┴)_╓─!├>╘8&*╫╟&$╟_:0&-\!@@╟1:╬╬╤┬╠╧!┬.╙1┬,╙┴@8╦> 8
  1327. ═2?]╔ 8╫╔&!┬═╪╤┴)_╓─!├>╨8&*╫╞&$╟_:0&-[╤@@╟1:╬╬╤┬╠╧!┬.╥╤┬,╙!┬═
  1328. ═╫╤┬-┌!┬═╪┴┬-┌╤┬═┘1┬-[┴@@╟1:╬╬╤┬╠╧!┬.╥1┬,╥┴┬═╪!┬-┌1┬═╪╤┬-[!┬═
  1329. ═┘┴┬-[╤@@╟1:╬╬╤┬╠╧!┬.╤╤┬,╥!┬╔ (6├╔0*%╔*─ ╚@┬@ )&├╥-#[┘╩3*╘/:┼
  1330. ═╔*╓_&(╓[&*╫ &(╓\&*╫!&(╓]&*╫"&(╓^&"".%┌╫#&(╓[&*╫$&(╓\&"".%┌╫%
  1331. ═&(╓]&*╫&&(╓^&"".%┌╓_&(╓[&*╫ &(╓\&"".%┌╫'&(╓]&*╫(&(╓^&"".%┌╫)
  1332. ═&(╓[&*╫*&(╓\&"".%┌╫!&(╓]&*╫"&(╓^&"".%┌╫+&(╓]&*╫,&(╓^&"".%┌╫#
  1333. ═&(╓[&*╫$&(╓\&"".%┌╫-&(╓[&*╫.&(╓\&"".%┌╫%&(╓]&*╫&&(╓^&"".%┌╫'
  1334. ═&(╓]&*╫(&(╓^&"".%┌╘8╘$─"├1├0╩0┴% ╚4"3,41&*╫╬&&╫╧&!┴═\!@8:8"╩
  1335. ═╧8 :┴?╥%_┴┬═┌!┴═┌1@8;>╚8┴?╠@┌!88╔?═╔0(╓[&!┬┼_╚7\╦>╠8;>╨8&&╫═
  1336. ═&(7[(.@6&*7[:4"-╧!┴@&*7[1?╨╨-:7[$ ╒)_╓─!┴?╠8╔?╤)_╓─!╩0"@"4╔╞
  1337. ═^┘ #&&7\┬-#╒2╞;[2╞;[2╞;[2╞;[2╞;[2╞;[┴?╒@╔?╠╨"┴┬┼_$╟_:0%,.!=)
  1338. ═_╓─!┴?╬╔ * )2╞;[─ ,89?╥(╘/5*9╧═*9╧═*9╧═*9╧═*9╧═*9╧╬%_:7[$ ,@
  1339. ═:1=)_╓─!┴?═@╚@"]>!?╨!╥#2_^┴,:╤=@#5-/34542$┼.1╥!#2$]+140@.┬@-
  1340. ═ *╓[&(7[╦;╘8┴?╓═╧!┬%_*╓^&(7^╩0"%╚┌4"┴:0╪╔?╫┼^[ 2╔?┌─_(7\┴/┌┼
  1341. ═^┌3]┴/╬%_>7[┴?╞╞^┌7[2─╔*2╔ %╚("$╚╤┴┼╔(6─.*7^┘?╥╨!*7\┘?┌%^╠7┘
  1342. ═╠%┬─_+╘ &1&├─:.┼^4╔)_╓─!╤/┌╨(╬┴┼^╔ #╥.7┘2+╘ &1 *1:.%╚╙ "┘╩2╔
  1343. ═@!&├─:-╚┘/╫0╫╓#╚9?╩0 ╪├┼^4┬] !─0"─6├┴:,╨ ╬:─╩8 1╚┘&├:.3]╘-]@
  1344. ═╔/╥] !─1╚┘&├╔?╔*2?]╔ <3^╠"[(9?╞0&^├┼^─┬] !─0"─6├┴:,╨ ╬:─╩8 1
  1345. ═╚┘&├:$╤^&$┬] !─1╚┘&├:,3^╘--@┬!┴┼^9 ;┌.7┌2+╘ &1 *1:.%╚╙ "┘╩2╔
  1346. ═@!&├─:-╚3*╘82+╘ &1&├─:-╚╤/[0╘╞"═&- ╔]8╘8╘&                  
  1347. ═                                                            
  1348. ═              " 0" 0" 0" 8! (! (! (!@$ @$ @$ @& 0" 0" 0" 8! 
  1349. ═(! (! (!@$ @$ @$ @& 0" 0" 0" 8! (! (! (!@$ @$ @$ @& 0" 0" 0"
  1350. ═ 8! (! (! (!@$ @$ @$ @& 0" 0" 0" 8! (! (! (!@$ @$ @$ @& 0" 0
  1351. ═" 0" 0                                                      
  1352. ═                                                            
  1353. ╚                                                        
  1354.  
  1355. END
  1356.  
  1357. BEGIN 666 CUBE3D.S
  1358. ═ ' ╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*@╘╩╚*"@╚*"@╚*"@
  1359. ═╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@*@╘╩╚'-415!(14┌@:┼5$1*"@╚*"@╚*"@
  1360. ═╚*"@╚*"@╚*"@*@╘╩╚&=%3╒)'1:!╘05┼,3╒*@╚*"@╚*"@╚*"@╚*"@╚*"@*@╘╩
  1361. ═╚'-405)4140┌╚#<╧,3$╧.32@╚*"@╚*"@╚*"@╚*"@*@╘╩╚&9)3─┼32$5$.╩ ╫
  1362. ═+╙$┘+╙─╘╚*"@╚*"@╚*"@╚*"@*@╘╩╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@
  1363. ═╚*"@╚*"@*@╘╩╚'=%3$╨╠╚$┼&╚$%,3*!'3╘53╚%=%3$╥@5$┴)4┌"@*@╘╩╚%!2
  1364. ═3╘=204╓@5╘┼,3*!23╒1!5$6@0:!#54)%+╩"@*@╘╩╚*"@╚*"@╚*"@╚*"@╚*"@
  1365. ═╚*"@╚*"@╚*"@╚*"@╚*"@*@╘╩╚'1(25.@4%)/1╒)!3:!)4┌!)3┼1%3─1%1*!4
  1366. ═3┌"@*@╘╩╚$%#0╘]-4$%.6:!42$6@05)424-,1:!)3╩"@╚*"@*@╘╩╚&,]:$%#
  1367. ═2╘┼.1╥╥@:┼5,6: ┘-*!)4╒-512┌@╚*"@*@╘╩╚&9/4╩!$151!24╤3╚$].╚%1(
  1368. ═25.@4%)/1╒)!32╥@*@╘╩╚%)%042@5$┴%╚$%25$┼#3$4┴╚*"@╚*"@╚*"@╚*"@
  1369. ═*@╘╩╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@*@╘╩╚'=2251%╚%1/
  1370. ═╚%53(:"@╚*"@╚*"@╚*"@╚*"@╚*"@*@╘╩╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@
  1371. ═╚*"@╚*"@╚*"@*@╘╩╚%5.*$)%12┼-3┌"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@*@╘╩
  1372. ═╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@*@╘╩╚%9)╚*"@╚*"@╚*"@
  1373. ═╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@*@╘╩╚$╪╚24╪╔1┌"@╚*"@╚*"@╚*"@╚*"@╚*"@
  1374. ═╚*"@╚*"@*@╘╩╚$%212┴42*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@*@╘╩╚$4╔
  1375. ═64]5*$^@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@*@╘╩╚$┘,62╞@╚*"@╚*"@╚*"@
  1376. ═╚*"@╚*"@╚*"@╚*"@╚*"@*@╘╩╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@
  1377. ═╚*"@*@╘╩╚$%33"┴23╒-%*45%4*"@╚*"@╚*"@╚*"@╚*"@╚*"@*@╘╩╚*"@╚*"@
  1378. ═╚*"@╚*"@╚*!%+─4╬0╒5-34┼.1╒.@╚*"@*@╘╩╚*"@╚*"@╚*"@╚*"@╚*"@╚*"@
  1379. ═╚*"@╚*"@╚*"@╚*"@*@╘╩╚' ╬<╥┌@=$┴)4┌!705.@5╒))5%1%3╩!54╘┼.1┌"@
  1380. ═*@╘╩╚*"@╚*"@;4523$┼.╚#$╥."┌@╚'=)5$┬@0:"@╚*"@*@╘╩╚*"@╚*"@3$┼4
  1381. ═5$╤%╚$╒/1$┼&24-!5$┼/3╩!)5*"@*@╘╩╚*"@╚*"@5╘┼,3*!73╒)+╚$9)3─6@
  1382. ═5╘┼42*"@╚*"@*@╘╩╚*"@╚*"@;4523$┼.╚#8╘+╩"@:4:@64]5╚*"@╚*"@*@╘╩
  1383. ═╚*"@╚*"@1$].)╒2@2$%61:!%251(15(╬+┬┌@╚*"@*@╘╩╚*"@╚*"@5╘5,3"╥@
  1384. ═5╘6@04╤,╚$┴!5─6@3╒52╚*"@*@╘╩╚*"@╚*"@3$┼45$╤%╚$9!54╤44╥┌@╚*"@
  1385. ═╚*"@╚*"@*@╘╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*┬╚╩*@╘-(&]╥
  1386. ═9╥ ─,3 ╨, ╘-*╩!├3╘┘35$%.5%,-#6)╒9╞8╤(&5╤=2 ─,╙ ╨," [9─┼24╒2@
  1387. ═0╘┴!4─%#5$52╚%-%5 ╒┬=69╞,┬!┼<74@)#,╪,# @.╫-%0╘].1*!#2$%204-4
  1388. ═15*@4╘54#6)╒9╞9┼<┬!┼<74@)&$╙(#═╨4─5354╒!0─╤9╚%1(1:!405!%╚%=/
  1389. ═3┬=4╚$)%╚%)53─┘)3─<->#$@97%╒("1╞8┬ [<$])3┼13╚$9/4╩!$4─%724┘'
  1390. ═╚$&@3$┼.10╒┘,2!┼<74@)&9├(#═╘2$531:!:15)/╚%!!1╘6@041$4─534╘53
  1391. ═#7@╥(&5╤=2 ─9╞0@.╘1/3┬=4╚$-/3─9,24-4╚%=)5$┬@8╞%╙:6,->3(@97%╒
  1392. ═("1╞90╒─>"!┼<74@)&8┘#61┘(&5╤=2 ─9╞$-=&5═<#$@97%╒("1╞8┬ [;╘:@
  1393. ═0╘]54┼-%+*!#3╒5,1*!#3╘┘&3$┼#5*!7251(╚%@╤#71┼;7 ╥(&5╤=2 ─9╞,@
  1394. ═.╫1%35!/4─%26:!605))04),15,-86-├(&5╤=2 ─9╞(@.╫1(15-%╚$9/55*@
  1395. ═5─%224%"3$53╚$%21:!54╘5$#6%╒>"!┼<74@)&9├(#═"6:!42$6@355,5$┼0
  1396. ═3$┼#051)3╘┌@4─]55$┼.10╒┼>'0@97%╒("1╞9 ╒╥96╘@97%╒("1╞90╒┌=&5═
  1397. ═<"!┼<74@)# ╥(#═╒4╘5$╚$9/4╩!"549&15*@4╒=!4"┌@╚&1/3┬=4╚%1/54-(
  1398. ═+@╘-86┘╟;6%╪(&5╤=2 ╤,├ @.╫1(15)%╚$%21: ╥*┼!)+╘%.1╘╒!6*!!3─=,
  1399. ═15,-;╓9╞<╓5╘(&5╤=2 ╓(#═╞3$]!5*!/1─93150┌╚%@]6$%#5%5!3"╚╥7─]&
  1400. ═1┼-%5 ╘-*╩!╓:6,-#79═8╫-┬(&5╤=2 ─9# ╤. ╒┬:╓=╬9"!┼<74@)&0╨,├ -
  1401. ═8╞]╥9&5╥(&5╤=2 ─9# ╥,0╒╙<╫1┴<╟0@97%╒(#$╙-#0@.╒)/5┌ ┘╚$┼.╚%-#
  1402. ═4─5%3╩!-14╒/4┼╞@052@,3 ╥- ╘-#2╩@:╘523─%,#0╒├:')╧=70@97%╒("1╞
  1403. ═9╞0╥#6=┼=&┼╬(&5╤=2 ─9╞9┼- ╘-*┬╚╩╚&╒!0╒)/4╨╘-;6]╓92!═86,-(&╤─
  1404. ═82!=,0╘@<╫1┴(%╘╥#2 \/#╨-#6=┼=&═┼>2!═86,@(#═╫04┼4╚$9/4╩!!╚$═%
  1405. ═65!215-3#7=┴:70@:╟-╥(&=┼=&┼╬#2!├;7 @(╙ ╨#2!┬97$@=╓%╔= ╘@/#╨\
  1406. ═#0╒─96)╒9╥!═86,@(#═╨4─┼.5*!!╚$-(05)!0╒1%4@╓@(&1╧╚# @(#═─3╘╪╟
  1407. ═5*!!4╒-%34),10╘-(&╤─82 ├73$-(&╔╙<┬!├:')╧=70-(#╪^/┬!╟971╦97─@
  1408. ═.╓%.1*!704┼4╚%1/╚$-/3┼1)3┼5%#2!├;7 @(╥=3)╥ [;5╞@4╘5#4─5#5*!3
  1409. ═5╘┼40╘┬@2╘59#2!┬;╞4@;#$-(&╔╙<┬!├;&5┴;╟5╨#2!╩;7 @9&]╬90╒╠,2!├
  1410. ═;7 @(╥=8)╥ [;5╞@4╘5#4─54╚$%"3╒)4╚$═%60╘@8╞┘┼(&1╧;╞4-(&╔═<"!├
  1411. ═;&5┴;╟5╨#2!╞:6╪-9&]╬92 \/#╨-#61┼8╟5╟82!═86,-(&1╧╚# -(&╤─82!=
  1412. ═,0╘@<╫1┴(#$╨,├0-(&9╔;@╒─;╓┘┼82 \/#╨-#7-┼=&)╒9┬!═86,@(#═╨552@
  1413. ═0┼5&1─524┌!72$521:!42$59╚$-!3╩!"1:!(55)4#2!╠9&$@(╙ ╨#2!╙=&$@
  1414. ═8╟5╞9╞5╥#2!╠9&$@>╟1┼;7 @.╒╔414╒0╚$-/3┼1!24┘3╚%1(1:!(24=(╚$)9
  1415. ═5$6@2$5210╘@<╫1┴(&)╒9╞9┼<┬╠╤#2 \/#╨-#2╚═+2╘═+2╘═+2╘═+2╘═+2╘═
  1416. ═+2╘═+2╘═+2╘═+2╘═+2╘═#0╘@;&1┴(",─,# -('-╘82!┬:╓=╬9 ╘@<╫1┴(&)╧
  1417. ═<╞1┼<@╘@;&1┴('9═8╫-┬#2!┴;╞0@(╥4╨,# ╨,3$╤,2 [<╘-2145.╚$╒%34]2
  1418. ═6:!43┌ ╤,#(╘#2!╧<╞$@(╥4╨,# ╤,# ╨, ╘@<╫1┴('9═8╫-┬#0╘@;&1┘(",╨
  1419. ═, ╘@;&1┴(",\='1┼>'0-('-╘82!╘96╒╨,0╘@;&1┴(",^='1┼>'0-('-╘82!╘
  1420. ═96╒╨,@╘@:╞╒╨('1╔=&╤┼#71╘97┴╘(&┴┼>" ┘,╙ ╒,3$╤,3$╤(#═#3$5!4╩!3
  1421. ═0╒)%14╪╠╚%=(251%+*!#4┼-2╚$1.#2!╘>'0@)┌"@╚*"@╚*"@╚*"@╚*"@╚$-5
  1422. ═0─4╙1"<╠,$0╠,$0-('1╪=" ╟╚*"@╚*"@╚*"@╚*"@╚*"@╚*!"62<╠,$0-(&┴┼
  1423. ═>" ┘9┬ [0╒┼!3@╘@='┴╘(">@╚*"@4╒1%4$┴%3╩!*541$)╨╘@:&5╪(#─┘#2!╘
  1424. ═>'0@)┌"@╚*!'14]21╘6@5$%93$]2)╥╨╨1"╨╨1 ╘@:&5╪(#┼┬#2!╘>'0@)┌"@
  1425. ═0╘┴%0╘╬@3╒54╚%1(1:!*54╤9╚#─╘╚$┼34╒5%╚$]&)╥╨╨1 ╘@:&5╪(#─╓#2!╘
  1426. ═>'0@)┌"@0╙╒(04-+24┘')╨╘@:&5╪(#┼┬#2!╘>'0@)┌!&3╒*@34]21:!$151!
  1427. ═24╤3(2<╠,$0-(&┴┼>" ╨9#%─,60┘93$╥#2!╘>'0@)╘8╤+╘8╥)╥╨┘,@╘@='┴╘
  1428. ═(">@+:!)3─,╧1$5#╚%@═4─]4051)3╘╪╟+#!$#2!╚97@@,60╤9#$╥#2!╘>'0@
  1429. ═)╘8╙+╘8╘)╥╨┘,@╘@='┴╘(">@+:!)3─,╧1$5#╚%─═4─]4051)3╘╪╟+#!$#2!╚
  1430. ═97@@,60╤9#$╥#2!╘>'0@)╘8╒+╘8╓)╥╨┘,@╘@='┴╘(">@+:!)3─,╧1$5#╚%╚═
  1431. ═4─]4051)3╘╪╟+#!$#2!╚97@@,60╤9#$╥#2!╘>'0@)╘8╫)╥╨┘,@╘@='┴╘(">@
  1432. ═4─531513)╥╨╨1 ╘@='┴╘(">@╚%!215-3╚%&@5$^@455)5"<╠,$0-(&┴┼>" ╨
  1433. ═9# ╒#2!╘>'0@)┌"@╚*"@╚%!215-3╚$%.6:!+15╞@5$^@0─5'24╪╟+#!$#2!╚
  1434. ═97@@,# -=&┼╘;&4@;&1┴("┴╘96╒╨,2─╠>0╘@8╞5╤(#╔├;╓┘╘#2!╩<╫(@8╓┴╥
  1435. ═;╫5╘#2!╔;╟─-(&)╬92!╘:71╠90╘@:6┘├('1┼;7 ╥#2!╩;7 @=&┼╘;&4-.╞-╧
  1436. ═;╟0@/├╪^(&=┼=&═┼>0╘-*┬╚╩*╩!╙152@55"@5$%"3$53*#\╔#0╘╩╚'1!0─╤%
  1437. ═4┌!!4─6@0╒524─5.5$╤9╚%-%5*!54*!)3╩!┬87-╔8╨╘╩╚$%.1*!"6:!42$6@
  1438. ═05-314╒"3$52+@╘-=&%┬;&5╙#0╘╩*┬╚╩╚&-,14%2╚%-#4─5%3╩!!3─2@4╘54
  1439. ═╚%50╚")"251-05 ┬#0╒╙971╒<"!╠9&$@(╙$╘-╨╘@:╟-╥(&-╚<╞]╒= ╘@;&1┴
  1440. ═(",\<╫-╘87)╘#2!┴9&,@(╙$╥(#═╘2$6@1╘]!3*!)4┌!43┌!#14┘415*@5$┴%
  1441. ═╚$=205!(24-3#2!╙=&$@=&5═<#$@.╓-/3%5-3╩ ╤,@╘@;&1┴(",^<╫-╘87)╘
  1442. ═(#═╥3╒>@.0╘@<╫1┴('1┼;7 ╤*╙$@.╫-╙=&%╥=*!03╘┼.5%.@5$^@4─]7╚#─-
  1443. ═(&╤─82 ├,# -(&╤─>2 ├,# -(&╤─>" ├,# @.╒┬@5╘┼,3*!#3╒5.5* ╤-╩!2
  1444. ═3╒=3╚$9/4╩!54╨╘@8╓╤├#0╘┌;&]╧<"!╙=&$@*'1┼;7 ╤*2╤┘#2!╔;╟─-(&%─
  1445. ═8╥ ├,38-(&)├8╥ ┌;&]╧< ╘@8╓╤├#2!╠9&$@=&5═<#$-(&%─8╥ ├-# @.╓┘%
  1446. ═142@5$^@041$╚#0╨╚%1/╚%1(1:!"05-%╚%!/24┘415(-('-╘82!╘96╒╨,2 [
  1447. ═=$^@2┼5-4*!43┌!42$6@3─585*!23╒<-(&╤─82!╘96╒╨,2╠╤#2!┴9&,@(╙ ╨
  1448. ═(#═╘04═%╚$-!4─6@3╘:@0╘%24─┼%4╨╘@<╫1┴('1┼;7 ╤*╙$-(&╤─>2 ├,# -
  1449. ═(&┼╬> ╘@='┴┴(" [>*!)4┌!!3%-/╚$%.╚$┼.1$58╚$┼.5$^@5$┴%╚$-(05)!
  1450. ═0╒1%4╩!.54╒"15(-(&-╨>" ├,38-(&)╬92 ┌;&]╧<" [;─5%1*!43┌!$3┌!)
  1451. ═5* ╤-╩!424╒%4╨╘-(#╪^/┬!─96)╒9╥╨╟,┬<-*┬╚╩*╩!╙152@55"@0┼5&1─52
  1452. ═4╨╘-(&╤─82 ├/&)╒9╞8╤#2!╙=&$@8╟5╞9╞5╥#2!╠9&$@(╙┘┬=69╞,0╘@<╫1┴
  1453. ═(&)╒9╞9┼<┬╠╤#2!╙=&$@>╟1┼;7 @.╒╔414╒0╚%=)3$╥@34%+1:!,249%╚%-)
  1454. ═35!,1:!&3╒*@55,-(&╤─82!╓;6-╙8@╘@86┘─(",┼,3$╤,3 ╨,#$@.╫-405)4
  1455. ═╚$┴%4─6@4╘^@5$┴!5*!35╘%0╚$)51─9%4┼.@5╘┼,3*!73╒)+╚%))1╘┴4#2!╧
  1456. ═<╞$@(╥4╨,# ╨,3$╤, ╘@<╫1┴('9═8╫-┬#0╘-*┬╚╩*╩!╙152@55"@24┘)5$┼!
  1457. ═3*!604╤515,-#6┼╬:70@;&1┴(",╨, ╘@<╫1┴(&1╙> ╘@<╫1┴(&1╙>0╘@<╫1┴
  1458. ═(&1╙>@╘@<╫1┴('-╪#2!╙=&$@<╫─-('-╘82!╙>@╘-(#╪^/┬!─96)╒9╥╨╟-"<-
  1459. ═#2╚═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═#2╩@;4%)3╩!,3╘]0
  1460. ═#0╘╩*┬╚╩╚&=%5*!+15┼04─534╨╘-;6%╔;@╒╦<')┼<╫,@:╟-╥(&=┼=&┼╬#2!├
  1461. ═;7 @(╙$╙,╥ [9├$_#2!┬;╞4@.╞8╥#2!╠9&$@9'-╪#2!├;7 @(╓%╬9╓╒┴>"\╥
  1462. ═(#═╬3┌!-3╒)%╚%1(04┌@4$─-(&)┼<2 ┌8╓]╬= ╘@:6┘├(&1╙>" [3╒1(15)7
  1463. ═25-%╚$┼.0╒)%05-%╚%@═4─]4051)3╘╪-(&╔═<" ┌8╓]╬= ╘┌9├(@8╓╒╨(",╤
  1464. ═,╙<@.╓8╥/╨╘@8╞┘┼(#╔╞,╨╘@;&1┴(&1╙> ╘@8╞5╤(#╔├;╓┘╘#2!─96,@9'-╪
  1465. ═#2!╩;7 @.╞-╧;╟0-.╞8╙(&-═<" ├,3,╘#2!┬;╞4@.╞8╘#2!╠9&$@9'-┘#2!├
  1466. ═;7 @(╓%╬9╓╒┴>"\╥#2!┬97$@.╞-╧;╟0-(&┼╬8╥!─<╫─@.╓┼.0╒)%05-%╚%─═
  1467. ═4─]4051)3╘╪-(&╔═<" ┌8╓]╬= ╘┌9├0@8╓╒╨(",╤,╙@-(&)╬92 ┌9├4-(&╤─
  1468. ═82!─<╫─-(&)┼<2 ┌8╓]╬= ╘@9&5├(&1╙>0╘@:╞╒╨(#╔├;╓┘╘#3╔╞-2!├;7 @
  1469. ═(╙$╙-0╘@8╞┘┼(#╔╞-@╘@;&1┴(&1╙>@╘@8╓╒╨("-┴;╞=═87@╧,@╘@8╞5╤(#╔├
  1470. ═;╓┘╘#2!╔;╞,@9'-┌(#═:+5)/5$%424].#2!╩;7 @.╞-╧;╟0-.╞8╓(&-═<" ├
  1471. ═,3,┘#2!┬;╞4@.╞8╫#2!╠9&$@9'-┌#2!┬97$@.╞-╧;╟0-(&1┼8╥!─<╫╚-(&╔═
  1472. ═<" ┌8╓]╬= ╘┌9├<@8╓╒╨(",╤,╙8-(&)╬92 ┌<0╘@:╞╒╨(&┼╬:70-.╟$@8╓╒╨
  1473. ═(",╟42<@.╒&@455)5%,-(&)╬92 ┌8╓]╬= ╘@:╞╒╨(&-╠96%╬=7 -#3╔├;╓┘╘
  1474. ═#2╩@/├╪^╚&1┼8╟5╟+"<╒)╨╘-*┬╚╩*╩!╒4$1!5$6@04┘'3$53#0╒╒<&1┴=&4@
  1475. ═8╓╤├#2!╠9&$@<╫@-(&%─8╥!─<╫@-(&-═<" ├86┘╟;6%╪(#═┴4─6@5╘6@/├╓@
  1476. ═34%824╒53:!!3─=,13\-(&)├8╥ ┌8╓]╬=#$-('-┬8╥ ├86┘╟;6%╪(#╔╔1┬!3
  1477. ═3╥╨@4─53150-.╞-╧;╟0╤('-╘82!╙> ╘@8╓╤├#2!╠9&$@<╫─-(&%─8╥!─<╫─-
  1478. ═(&-═<" ├86┘╟;6%╪#2!┬8╓,@.╞-╧;╟0╥#2!╙8╞,@(╓%╬9╓╒┴>" [<╘%-1:!$
  1479. ═14%,#3╔├;╓┘╘,┬!╙=&$@<╫─-(&-╠8╨╘@;&1┴('-┌#2!┴9&,@9'-┌#2!├;7 @
  1480. ═(╓%╬9╓╒┴> ╘@8╞-├(#╔├;╓┘╘,╨╘@<╓)├("-┴;╞=═87@-.╞-╧;╟0╙('-╘82!╙
  1481. ═>@╘-#2╚╩*┬╩@<─]4051%╚$-/3╒)$24┘!5$53#0╒╥;╫1┴=&4-#2╚╩*╩!╞25)3
  1482. ═5"╥@0╘%,0╒5,051%╚%0╤+%0╥+"╪╬+┬╤4,3 -#2╚╩╚'173┌!-04-23╒.@5$^@
  1483. ═4╘┼-4$╤)1┼╞@3╒52╚$╤)1─4-861─82!═86,@(#═┴1$2@5%=/╚$%.1╘╤%4┌!4
  1484. ═3╘=%5$┴%4@╘@8╓╤├#2!╠9&$@73$-(&%─8╥!=,@╘@8╓╒╨("-┴;╞=═87@@.╓┼3
  1485. ═╚%1(1:!354╓@/╩ ╥*┼!)/╨╘@8╞-├(&1╧;╞4-('-┬8╥ ├86┘╟;6%╪(#═╔1╩!3
  1486. ═3╥╥@4╒5"5%)!0╒2@,┬╔020╒─;╓┘┼(#╨\/ ╘-<╫5┬82!═86,@(#═╙54)44─%#
  1487. ═5*!45╘^@04┘'3$53#2!╙96,-(&╤─82!=,0╘@<╓)├(%╘╥#2!┬8╫,@9&]╬90╘@
  1488. ═861├("-┴;╞=═87@@.╓]/4%,╠╚%=%╚$┘%142@5$^@041$╚#(╩4$─-9&]╬92 \
  1489. ═/#╨-#2╚╩╚&┘/5┌!#04╤#54╤!5$6@5#$╠5#(╠151#+@╘-(#╪^/┬!╙=6)┴+'-┘
  1490. ═.╫-┌#2!╙=&$@=#$@.╒0╤/5-9+5-:#2 ^/├╪@861─82╤╙>3═╙>@╘@<╫1┴('0╥
  1491. ═(#═4,├╒362═36@╘@/├╪^(&%─9&$╠<╫@[<╫╚-('-╘82!╘,╥ [5#,]4╒@╦4╒╚-
  1492. ═(#╪^/┬!╙=6)┴+'-╪.╫-┌#2!╙=&$@=#0@.╒0╘/5-8+5-:#2 ^/├╪@861─82╤╙
  1493. ═>#═╘,@╘@<╫1┴('0╒(#═4-3╒36"═4,@╘@/├╪^('-╒8╞$╠<╫@[=#$-('-╘82!╘
  1494. ═-┬ [5#8]4╒@═5#$-(#╪^/┬!┴9&1┴+'-╪.╫0╤#2!╙=&$@=#<@.╒0╫/5-8*╒0╤
  1495. ═#2 ^/├╪@<╫5┬82╤╘,├═╙> ╘@<╫1┴('0╪(#═4.#╒4,┬╒36 ╘@/├╪^('-╒8╞$╠
  1496. ═<╫─[<╫@-('-╘82!╘.2 [5#─]4╒─═4╒@-(#╪^/┬!┴9&1┴+'-╪.╫-┘#2!╙=&$@
  1497. ═=#$╨(#═4,3 ]4╒@╦4╒─-#2╩@952@5─])3$$┴#0╘╩*┬╩@;─585"╥@0╘%,0╒5,
  1498. ═051%╚&$╠8┬╤├+"╪╬+┬╤╔#0╘╩*╩!┴3─]42$52╚%5314953*!,25143$6@34%#
  1499. ═4─\-9&┼╓,┬!═86,@(#═─259)1$6@0:!324=.142@3┼5-0─52╚$)9╚#(-.╓┼4
  1500. ═╚$┼3╚$%34╒5-142@5$┴!5*!42$6@3┼5-0─52#2!┬<&╨@<&]╙(#═)4┌!)3╩!4
  1501. ═2$6@04-#54╒53$%43╒(-(&-╠8╨╘@96]╥(",─9╞8@.╫=%╚$┘%142@5$^@54╪═
  1502. ═3─5'051)5─6@5$┴%╚$┘534)%4@╘@861├(",╨,2 [0┼╞@5$%+24┘'╚$┼4)╒.@
  1503. ═0╘]-4$╤%345.5 ╘@;'-╥(" [1$┼6241%╚$)9╚%173╨╘@8╓╤├#2!┼;╫(@(╥1╞
  1504. ═9@╘@861├(",╨,2 [;4%+1:!)5*!.14=!5$┼61:!!1╘%)3@╘@:╞╒╨(&1╧;╞5─
  1505. ═:78-<&]╙(&╤╙<┬ @.╓┘534)%4╩!)4┌!03╒-)5$┼610╒─;╓┘┼9&┼╓(#╨\/ ╘-
  1506. ═;75╠,┬!═86,@(#══54╤425!,6:!!╚%-)1╘┘%1*!.54╒"15*@0┼╞@,@╘@8╟!╠
  1507. ═('!╧<╓╘-(&-╠8╨╘@96]╥(",─9╞8-(&%─8╥ ├)# ╤#2!┴<╓╨-(&-╠8╨╘@96]╥
  1508. ═(",─9╞8-(&%─8╥ ├)# ╤#2!╩;7 @9&]╬96╒╒; ╒╨;╫-═(&%╙; ╒─;╓┘┼;75╠
  1509. ═(#╨\/ ╘-*┬╩@;─]41:!42$%4╚%=%╚$%21:!#55)214┘43%╞@34%+24┘'╚$&@
  1510. ═34┼.3╒*@3$5!4 ╘╩*╩!/1╩!&04┼42*!42$%4╚$┘/╚$]615)&3$]74┌!724╤,
  1511. ═╚$]#0╒52+@╘-.╞-┴;&-┴(&-╠8╨╘@;&1╪('0╤#2!╠9&$@8╓]╙+'@-(&╤─>"!╘
  1512. ═,@╘@861├(&-╧<╥╤╪#2!╙=&$@83$╤(#═┴/2┴#3╒,╚5#$╔*╘-/4╥┴4,┬─╔+╙(-
  1513. ═.╞-┴;&-┬(&╤─>"!╘,0╘@;&1┴('-╔;┬╤╪#2!╙96,-(&╤─>"!╘,@╘@<╓)├('-╔
  1514. ═;┬╤╪#2!╙=&$@8├$╥(#═┬/2┴324╪╚5#$╔+5-)3┬┴4,┬─╔+╙(-.╞-┴;&-├(&╤─
  1515. ═>"!╙>0╘@;&1┴('-╔;┬╤╪#2 ^/├╪@;75╠,@╘@<╫1┴(&,╤,╥ [8╙╒324╪╚4╒─╔
  1516. ═#3╔├86╤├9"!╙96,-(&╤─>"!╘. ╘@;&1┴(&-╧<╥╤╪#2!╠9'@@=#<-('-┬8╥!├
  1517. ═;╫,╠> ╘@<╓5├#2!╠9'@@=#4-('-┬8╥!├;╫,╠> ╘@8╓╤├#2!╠9'@@=#8-(&%─
  1518. ═8╥!├;╫,╠>" [9$─]*$-/4╥┴4."─═0╘]3*%0╫*2═#3╒,╚5#8╔+4-/4╥┴4-2─╔
  1519. ═+╙(-(#╪^/┬!─:78╥#2!├;&,-(&╤─>"!╘,╨╘@861├('-╔;┬╤╪#2!╙96,-(&╤─
  1520. ═>"!╘- ╘@<╓)├('-╔;┬╤╪#2!╙=&$@9#(╤(#═─/2┴324╪╚5#,╔+5-)3┬┴4-"─╦
  1521. ═9$─╔+╙(-.╞-┴;&-┼('-┼8╨╘@;&1╪('0╒#2!╠9&$@<╓┼╬+'@-(&╤─>"!╘-@╘@
  1522. ═<╓)├('-╔;┬╤╪#2!╙96,-(&╤─>"!╘-╨╘@<╓)├('-╔;┬╤╪#2!╙96,-(&╤─>"!╘
  1523. ═. ╘@<╓)├('-╔;┬╤╪(#═┼23╘╚4╘┼.*%0╒*2╒324╪╚5#8╔+5-)3┬┴4-╥─═4╘┼.
  1524. ═*%0╪*2─╧,@╘@/├╪^(&1╔=├(-(&-╠8╨╘@;&1╪('0╙#2!┴9&,@8╓]╙+'@-(&-╠
  1525. ═8╨╘@;&1╪('0╘#2!┴9&,@8╓]╙+'@-('-╘82!┼,├(@.╓4]*$-/4╥┴4,╥─╦0╘]3
  1526. ═*%0╘*2═┼22─╧,@╘┌8╓%╠8╓8@;&1╪('0┘#2!╠9&$@<╓┼╬+'@-('-┼8╨╘@;&1╪
  1527. ═('0╤, ╘@<╓)├('-╔;┬╤╪#2!╙=&$@9├(╙(#═╞/2┴324╪╚5#─╔+5-)3┬┴4,3 ╔
  1528. ═*2\╥#3╔├86╤├9╥!╠9'@@=#8-(&╤─82!╙:6╪╠> ╘@<╓5├#2!╠9'@@=#@-('-┬
  1529. ═8╥!╙:6╪╠> ╘@<╓5├#2!╠9'@@=#<-('-┬8╥!╙:6╪╠> ╘@<╓5├#2!╠9'@@=#4-
  1530. ═('-┬8╥!╙:6╪╠>" [9╘─]*%-)3┬┴4-┬─═4╘┼.*%0╪*2╒324╪╚5#<╔+5-)3┬┴4
  1531. ═-2─╔+╙(-(#╪^/┬!─:78╥#2!├;&,-(&╤─>"!╘- ╘@861├(&-╧<╥╤╪#2!╙96,-
  1532. ═(&╤─>"!╘,╨╘@<╓)├(&-╧<╥╤╪#2!╙=&$@9╙,╤(#═╟/2┴#3╒,╚5#0╔+4-/4╥┴4
  1533. ═,╥─╦9╘─╔+╙(-(#╪^/┬!─96)╒9╓$╠9╙,╤#2 ^/├╪@9&5┬=6<╠)╘<╟#3╔├86╤├
  1534. ═:"!├;&,-(&╤─>"!╘-@╘@;&1┴(&-╧<╥╤╪#2!╠9'@@=#<-(&%─8╥!├;╫,╠> ╘@
  1535. ═<╓5├#2!╠9'@@=#4-('-┬8╥!├;╫,╠> ╘@<╓5├#2!╠9'@@=#@-('-┬8╥!├;╫,╠
  1536. ═>" [:$─]*$-/4╥┴4-┬─╦0╘]3*%0╫*2╒#3╒,╚5#4╔+4-/4╥┴4."─╔+╙(-(#╪^
  1537. ═/┬!─:78╥#2!├;&,-(&╤─>"!╘,╨╘@861├('-╔;┬╤╪#2!├;&,-(&╤─>"!╘- ╘@
  1538. ═861├('-╔;┬╤╪#2!╙=&$@:#,╥(#═╚/2┴324╪╚5#,╔*╒-)3┬┴4-"─╦:$─╔+╙(-
  1539. ═.╟=╚97<@8╓╤├#2!╠9'@@=#─-(&╤─82!├;╫,╠> ╘@;&1╪('0╤, ╘@861├(&-╧
  1540. ═<╥╤╪#2!╙=&$@:3,╙(#═╔/2┴#3╒,╚5#─╔*╘-/4╥┴4,3 ╔*2\╥#0╘╩*╩!╔5"=3
  1541. ═╚$%,3*!$3╒=.2$┼,3*!&4─]-╚$┴%4─4╬#0╘╩*╩!╥3╒1!5$4╠╚%!23╘╔%0╒0╠
  1542. ═╚$%.1*!35$]21:!42$6@4$])3┼13#61╧=╓┘╚:6╤╠(&╤─82!┴,3$@.╫1(25.@
  1543. ═25.@1╘545$┼.1┌!43┌!"1:!!╚%)%04╥@34534╨╘@<╫1┴('1┴#2!╠9&$@8├$╥
  1544. ═(#═╘2$6@4─5!4╘].╚%1(25.@25.@1$].10╘@<╫1┴('1┬(#═)4┌!43┌!-04═%
  1545. ═╚%1(1:!#3╘1%╚$&@3$┼45$╤%#2!╠9&$@8╙$╙(#═%05-)15*@5$^@4─5!1* ╚
  1546. ═04┘$╚$1%0┼5'(2─-('-╘82!╘8╨╘@;&1┴(&0╥,2 [=$┴%4╘6@05)%╚$%,3*!4
  1547. ═14╒03╒)!4┼╞@3$]#051)3╘┘3#2!╙=&$@=&0@.╫53142@0┼╞@5$┴%╚%!23╘╔%
  1548. ═0╒1)3╘┌@4╒5"4─]55$┼.12╪-(&╤─82!┼,├(-('-╘82!╘92 [;╒1(15)725-%
  1549. ═+*!42$521:!73╒5,1*!"1:!%24=(5 ╘@;&1┴(&8╥,╥ [3$].1┌!23╒5424┘%
  1550. ═4┌!(15)%+@╘@<╫1┴('1╞#2!╠9&$@9╙,╤(#═┬552@252@5╘]53$2@0─6@4╘┼'
  1551. ═3─┼&24-!3┼1,6:!&05-415(-('-╘82!╘9╨╘@;&1┴(&@╙,@╘@<╫1┴('1╚#2!╠
  1552. ═9&$@:3,╙#2!╙=&$@=&─-#2╩@8:!.14%4╚$╒!0╒)/#6┘┼9╥!═86,@(#═├2$%.
  1553. ═1╘6@5$┴%╚%-)1╘┌@3╘:@0:!45╘\╟4┌!#3╘╒03$5-14┘4#2!├;&,-(&╤─82!=
  1554. ═,2 [3┼5-0─52+@╘@96]╥(",─9╞8-(&%─8╥ ├)# ╤#2 \/#╨-#2╩@<#$]6╙&@
  1555. ═,: ╤70╘@:╟-╥('!╥;╓╔┼8╫0@.╫5.4─],3*!42$┼3╚%=(3╘╤%╚%1(24┘'#2!╠
  1556. ═9'@@='@╤(#╠╚4╘]24┼╞@04)/552@5$┴%4╘6@5%=/╚$╤)3─53*0╘@;&1┘('1┘
  1557. ═,2 [*%-%1:!╨<╞]╩96-╘╚$9/4╩!214%33╘┌@5╘┴9*0╘@<╫1╪(' ╤>" [9─]2
  1558. ═╚$&@4%)%5%19╚$))1┌!34$5%1*!)3─-214%312$-('-╘>2!╨,7─-*╩!╨,├╒;
  1559. ═,: ═,: ╤70╘@/├╪^(&┘┼9╥╤┬,3(@.╓-(04┘'1:!42$531:!%3$5-14┘44╨╘@
  1560. ═<╫1┴('1┬#2 ^/├╪@;╞5╟+&4╥,┬ [<╘┼.0╘6@6:!)4┌!.3╒>@+3$-('-╘82!╘
  1561. ═90╘@/├╪^(&┘┼9╥╤╚,╙(-('-╘82!╘: ╘@:╟-╥('!╥;╓╔┼8╫0-(&╤─>"!╘>#$-
  1562. ═(&╤─>2!╘>3$-('-╘>"!╨,╟@-('-╘>2!╨,╟─-*╩!╨,╙╒;+3&@+3&@,5╘-(#╪^
  1563. ═/┬!╬96<╠83$╤#2!╙=&$@=&$-(#╪^/┬!╬96<╠9#(╤#2!╙=&$@=&0-(#╪^/┬!╬
  1564. ═96<╠9╙,╤#2!╙=&$@=&<-(&╔╙<┬!╨<╞]╩96-╘#2!╠9'@@='@╤#2!╠9'─@='─╤
  1565. ═#2!╙='@@<#-╪#2!╙='─@<#-┘#2╩@<#0]6╥╘╤╚#&@,5╘-(&╤─82!┬,3(-('-╘
  1566. ═82!╘8@╘@;&1┴(&4╥,@╘@<╫1┴('1┼#2!╠9&$@:#,╥#2!╙=&$@=&@-(&╔╙<┬!╨
  1567. ═<╞]╩96-╘#2!╠9'@@='@╤#2!╠9'─@='─╤#2!╙='@@<#1╪#2!╙='─@<#1┘#2╩@
  1568. ═<#@]6╥╘╤╚#&@+3%=#2 ^/├╪@;╞5╟+&,╤,╨╘@<╫1┴('1├#2 ^/├╪@;╞5╟+&8╥
  1569. ═,╨╘@<╫1┴('1╞#2 ^/├╪@;╞5╟+&─╙,╨╘@<╫1┴('1╔#2!╩<╫(@<')╧:╞5├= ╘@
  1570. ═;&1╪('1╪,0╘@;&1┘('1┘,0╘@<╫1╪(' ╪> ╘@<╫1┘(' ╪>0╘╩╚' ╫/5╠═,: ═
  1571. ═,: ═,5╘-(#╪^/┬!╬96<╠8├$╥#2!╙=&$@=&(-(#╪^/┬!╬96<╠93(╥#2!╙=&$@
  1572. ═=&4-(#╪^/┬!╬96<╠:#,╥#2!╙=&$@=&@-(&╔╙<┬!╨<╞]╩96-╘#2!╠9'@@='@╤
  1573. ═#2!╠9'─@='─╤#2!╙='@@<#=╪#2!╙='─@<#=┘#2╩@<#8]6╙&@+3&@+3%=#2!╠
  1574. ═9&$@83$╤#2!╙=&$@=&$-(&╤─82!─,├$-('-╘82!╘9 ╘@;&1┴(&<╙,0╘@<╫1┴
  1575. ═('1╟#2!╩<╫(@<')╧:╞5├= ╘@;&1╪('1╪,0╘@;&1┘('1┘,0╘@<╫1╪(' ╓> ╘@
  1576. ═<╫1┘(' ╓>0╘╩╚' ╒/5╠╤╚#&@+3%=#2!╠9&$@8├$╥#2!╙=&$@=&(-(&╤─82!┼
  1577. ═,├(-('-╘82!╘90╘@;&1┴(&@╙,@╘@<╫1┴('1╚#2!╩<╫(@<')╧:╞5├= ╘@;&1╪
  1578. ═('1╪,0╘@;&1┘('1┘,0╘@<╫1╪(' ╒> ╘@<╫1┘(' ╒>0╘-*┬╚╩*╩!├3$5!4╩!"
  1579. ═549&15(-#2 ^/├╪@<╓5╘8╟5╞#6-╠<╞)╒9┬!╠9&$@(╥0╨," [<%)%5%19╚%-4
  1580. ═4─%)1╘┴41─]25╘%21"╨-(&╤─>" ├)# ╪(#═╔╚%1(24┘+#2!╠9'─@(╥0╨, ╘┌
  1581. ═;&]╧<"!╙=&$@*&)╒9╞9┼<┬─╠>0╘@:6┘┘#2!┬;╞4@.╞╤╧;╫ -(&┼╬8╥!┬=69╞
  1582. ═97(╦,0╘@9&5╪#2!┬;╞4@.╞╤╧;╫ -(&╤─82!┬=69╞97(╦,0╘-*┬╚╩*╩!╞24┘!
  1583. ═3$╤9+*!$4─%7╚%1(1:!,24┘%4╥╪-#2!╠9&$@<#%╪(#═;,: ╤╚#%=#2!╙=&$@
  1584. ═='@╤#2!╠9&$@<#%┘#2!╙=&$@='─╤#2!╠9&$@<#)╪(#═;,: ═,: ╤70╘@<╫1┴
  1585. ═('1╪,@╘@;&1┴(' ╥>0╘@<╫1┴('1┘,@╘@:╟-╥(&1╥87<@.╓9)4┼-4╚$╤)3─4-
  1586. ═#2!╠9&$@<#-╪(#═;+3&@+3&@,5╘-('-╘82!╘>#$-(&╤─82!╨,╫─-('-╘82!╘
  1587. ═>3$-(&╔╙<┬!─<╞%╫(#═╙14-/3─2@3$┼.10╘-(&╤─82!╨-'@@.╒╠═,: ╤╚#%=
  1588. ═#2!╙=&$@='@╥#2!╠9&$@<#1┘#2!╙=&$@='─╥#2!╩<╫(@9')┴=╥ [=$┴)4─2@
  1589. ═3$┼.10╘-(&╤─82!╨,7@@.╒╠╤╚#&@,5╘-('-╘82!╘>#$-(&╤─82!╨,7─-('-╘
  1590. ═82!╘>3$-(&╔╙<┬!─<╞%╫(#═╞3╒525$┬@3$┼.12┌@╚&].1:!&04-%╚$1/3─4╬
  1591. ═#0╘@;&1┴(' ╒>" [6╙&@,: ═,5╘-('-╘82!╘>#(-(&╤─82!╨-7─-('-╘82!╘
  1592. ═>3(-(&╔╙<┬!─<╞%╫(#═╞259%#0╘@;&1┴(' ╓>" [6╙&@+3&@+3%=#2!╙=&$@
  1593. ═='@╤#2!╠9&$@<#9┘#2!╙=&$@='─╤#2!╩<╫(@9')┴=╥ [<╘┼8#0╘@;&1┴(' ╥
  1594. ═>" [6╙&@+3&@,5╘-('-╘82!╘>#(-(&╤─82!╨,╟─-('-╘82!╘>3(-(&╔╙<┬!─
  1595. ═<╞%╫(#═╙159%3@╘-(&╤─82!╨-╫@@.╒╠═,: ═,: ═,5╘-('-╘82!╘>#(-(&╤─
  1596. ═82!╨-╫─-('-╘82!╘>3(-(&╔╙<┬!─<╞%╫(#═┼24=(5 ╘-(&╤─82!╨,╫@@.╒╠═
  1597. ═,: ═,: ╤70╘@<╫1┴('1╪,0╘@;&1┴(' ╙>0╘@<╫1┴('1┘,0╘@:╟-╥(&1╥87<@
  1598. ═.╓┘)3─4-#2!╠9&$@<#┴╪(#═;+3&@,: ═,5╘-('-╘82!╘>#$-(&╤─82!╨.'─-
  1599. ═('-╘82!╘>3$-(&╔╙<┬!─<╞%╫(#═╘14╪-#2!╠9&$@<#1╪(#═;+3&@,: ╤70╘@
  1600. ═<╫1┴('1╪,@╘@;&1┴(' ╘>0╘@<╫1┴('1┘,@╘@:╟-╥(&1╥87<@.╓5,159%3@╘-
  1601. ═(&╤─82!╨-7@@.╒╠╤╚#&@+3%=#2!╙=&$@='@╥#2!╠9&$@<#5┘#2!╙=&$@='─╥
  1602. ═#2!╩<╫(@9')┴=╥ [=%=%3%9%(0╘-*┬╚╩*╩!╙5╘%0╚$)51─9%4┼,-#7-╫87!┬
  1603. ═=68@;&1┴('9═8╫-┬#2!┼;╫(@(╥0╨,┬ [<%)%5%19╚%1224-+62╥@14@_#2!╙
  1604. ═=&$@=╞╒├<╓(-(&╤─82 ├)# ╪#2!┼;╫(@>╟1┼;7 @.╒╔414╒0/4┴)1╘┬@0┼┼4
  1605. ═1:!*55-4╚$9,25!3#2!╙=&$@>╟1┼;7 @.╘)%5%=%14┌@)#,╨╚$%.1* ─,╙@-
  1606. ═#2!╩;7 @;6%╔;┬ [85)/54┘$╚$%.1*!!4─]53─2@5╘6@1╘\╬+┬╪-#0╘╩+2╘═
  1607. ═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+0╘╩╚'1(25.@4╒5"4─]55$┼.
  1608. ═1:!#04╤#54╤!5$53╚%1(1:!04─]*14-424].╚$]&╚'┬@04┘$╚'─-#7!╥;╓╔┼
  1609. ═8╫0@8╓╤├#2!╠9&$@=&<-(&%─8╥!╘: ╘@8╓╤├#2!┴9&,@=&─@.╫1(25.@25.@
  1610. ═4─]4051%1*!┌#2!├;&,-(&%─8╥ ├,3(╪(#═╫1:!!4─6@1╘])3─>@5$^@5$%+
  1611. ═1: ╤,├@╦6@╘╩╚#╪^/╩!─96)╒9╓$╠875╪#2╩@/├╪^╚&1┼8╟5╟+"=!)╨╘@=&%╪
  1612. ═(" [;─]7╚$┼4╚$┼3╚%)%0419╚$9/4╩!)3─1%6$┼.1╨╘@;&1┴('╔─:78╠>" [
  1613. ═=$%"3$6@3╘:@+40╧6@╘@<╫1┴(&%╒>" [=$┴)4┌!)4┌!&3╒*@5$┴%╚%!23╘╔%
  1614. ═0╒1)3╘╪-('-╘82!╥96╘@.╓╒53%1)4$╤9╚$-!3╩!#3$]"0─52╚&%╒> ╘-(&-╠
  1615. ═8╨╘@;&1┴('1┴#2!┴9&,@=&(-(&-╠8╨╘@861├('1├#2!╙=&$@86-├(#═╘2$┼3
  1616. ═╚$┼3╚%)/5$%4142@6 ╘@:╟-╥('-═=6╤╘(#═╙24=.142@355,5$┼03%╞@86-├
  1617. ═*╞%╒>"\╥7╞]╞9╟-┼= ╘@8╓╤├#2!╠9&$@86-├#3╔├;╓┘╘,2!┴9&,@(╙8╘(#═╧
  1618. ═1─93152@5$┴%╚$-/3╒)$24┘!5$4-*╩!╙146@0─5,3╒>@1─]2╚%1(1:!214%3
  1619. ═3╘┌@5╘┴9╚%1(25,-*╩!.15┴4╚$┼.4╒1254-424].╚$┼3╚$-/34╒%3┼1%1*!/
  1620. ═550-*╩!╘87┬@╚#═╬3╒>@>*!)4┌!8(0╘@<╫1┴('1╪,0╘@8╓╤├(" [9$^@5$┴%
  1621. ═╚%=(3╘╤%╚%1(24┘'╚$%'04┼.╚$9/4╩!┘#2!╠9&$@<╞5═#2!╙=&$@875╪#2!╠
  1622. ═9&$@=&0-(&%─8╥!╘90╘@8╓╤├#2!┴9&,@=&8-('-╘82!┴8╓,@.╫1(25.@25.@
  1623. ═4─]4051%1*!9#2!╩<╫(@<╓╒╒;'0@.╫-)1╘┘%1*!-54╤425!,6:!┴8╓,╩875╪
  1624. ═+╙)>;╓9╞<╓5╘#2!├;&,-(&╤─82!┴8╓,-.╞-╧;╟0╥(&%─8╥ ├-├0@.╓]&1┼-%
  1625. ═5*!42$6@0╘]/4─1)3─%410╘╩╚&9/4╩!33╘╒%╚$-/35!,151%3%╞@54┘+3─]7
  1626. ═3╩!214%33╘┌@5$^@344-*╩!42$6@24┘35%)50╒1)3╘┌@0─5,3╒>@1$]%4╘╪╟
  1627. ═5*!73╒)++╩"@<╘]-14┴/5╨╘╩╚%1(1:!╥='.@25.@34]$249924┘'╚'┬@04┘$
  1628. ═╚'─_/╙\-*╩!╘87╞@╚#═╙5$]21:!)3╩!┘#2!╙=&$@='─╤#2!╥=',@(#═╔╚$┴/
  1629. ═4$6@5$^@2$5#2┌!42$┼3╚%=/4─═3+@╘-*┬╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═
  1630. ═+2╘═+2╘═+2╘═+2╘-*╩!╙;75╠=#╩@."╒"252@4╘┼'3─5$╚"┴33╒)4+4]&*:!-
  1631. ═54╤425!,60╘╩#2╩@86-├*╞%╒>"\╥7╞]╞9╟-┼=* ═/╩!;86-├+*!┼>'1=╚* ╤
  1632. ═-┬╒"252@4─5354╤4╚*!,3╥╤(20╘╩#2╩@;─]41:!42$%4╚%1(25.@4─]55$┼.
  1633. ═1:!$259)1$53╚%1(1:!%3─2@4─5354╤4╚$)9╚#)>;╓9╞<╓5╘#0╘╩╚'┼54"╥@
  1634. ═04┘/5$┴%4╩!-04-23╥╪-9&┼╓;╓9╞(&╒┴8╥ @.╓1)5─┼$1:!"6:!42$6@1─╤/
  1635. ═052@3╘9&4╘54#2!╠=7 @;╓9╞<╓5╘(#═╥15!%052@3╘9&4╘54╚%1)3453#2!╠
  1636. ═<╫(@(#═┴╚$-/3┼1!24┘3╚$┴)1╘┬@0┼┼410╘@<╞]╥(&%├8╥ [86-├╚$┼3╚$╤/
  1637. ═5┌!"651%#2 ═+5╪-(#╨\/ ╘-#7-═=6╤╘(&-╠8╨╘@;&1┴(&%├8╥ [9─┼24╒0╠
  1638. ═╚$┼3╚%1(1:!215-53%2@4$]3251)5─6@3╒*@3─5'051)5─4_#2!┼;╫(@875╪
  1639. ═#2!┬;6─@.╞┘┼9╨╘-(&╤─82!┴8╓,@.╫1(15╞@05)%╚$5)5$┴%4╩!"3╒1(╚$┘%
  1640. ═1╘%4259%╚$]2#2!┬<&╨@.╞-╧;╟0╤(#═"3╒1(╚%!/4╘┼4259%#2!┼;╫(@(╥1╞
  1641. ═9┬ [:4┌@5$┴)4┌!#05-%+*!-04═%╚%1(14╘-(&%─8╥ ├)# ╤(#═"3╒1(╚%!/
  1642. ═4╘┼4259%(0╘@<╫1┴(&%├8╨╘@/├╪^(&┘┼9╥╤┴=7@@.╓╤)5%1,1:!-04-23┌!5
  1643. ═4╘5$╚$5!4─╤)15(╬#3╔├;╓┘╘,2!╠9&$@(╙ ╨(#══54╤425!,6:!42$6@5%=/
  1644. ═╚$┘534)%4┼,-(&╤─>2 ├)# ┘#5╒╠;╓]╨(&╤╙<┬ @.╫)%042@5$┴%╚$%25$┼#
  1645. ═3$6@1─]2╚$1%5$%)3%,╬#2!╥;╫(@86-├#2!┬8╓,@.╞╒╒;'0╤(#═╧4╩!&24=5
  1646. ═4─6@252@3╒54╚%┼/55)314╤&(0╘@8╓╤├#2!┴9&,@875╪#3╔═=6╤╘,2!─97─-
  1647. ═(&)╬92!=;&]╧< ╘@/├╪^(&1╔=╞]╞9┬ [<─5-3╒9%╚%1(25.@3$┼.1:!&3╒*@
  1648. ═0:!'14┘%4─%,╚$╒53%1)4$╤9#2!╙=&$@97┴╘#2!╥=',-#3╔╬96<@;&1┴(&%├
  1649. ═8╥ [;╘┘%╚$]&╚%1(1:!45╘^@25.@3─5'051)5─4-(&)═:2 ┌8╓]╬=#(-(#╪^
  1650. ═/┬!╬96<╠875╪(#═╧5$┴%4┼=)4╘6@250╟4┌!┴=7@-(&╔═<" ┌8╓]╬=#,-.╞-╧
  1651. ═;╟0╥(&5╧<┬ ├)&9╞(#═╘04═%╚%173╥=3╚$-/35!,14╒%3┼0-(&%─8╥ ├)# ╤
  1652. ═#2!╙=&$@86-├#3╔├;╓┘╘,╥!╠9&$@(╙ ╨(#══54╤425!,60╘@;&1┘(",─,#─-
  1653. ═76╤╧;╫ ╥(&╤╙<@╘@<╞]╥(&%├8╨╘@8╞-├(#╔═=6╤╘,@╘@8╓╤├#2!┴9&,@875╪
  1654. ═#3╔═=6╤╘,┬!─97─-(&)╬92!=;&]╧<#(-(#╪^/┬!─:79╧9╞8@.╓%'04┼.+*!$
  1655. ═259)1$6@0┼╞@5$┴%╚$]&1┼-%5 ╘@<╫1┴(&5╪= ╘@;&1┴(&%├8╨╘@8╟!╠(#╔╧
  1656. ═:╥ [<╘]-151(24┘'╚$┼3╚%)%04╤,6:!74─].1┌!)1╩!42$┼3╚$┼3╚$┘%1╘%4
  1657. ═259%+@╘@:╟-╥(&-╚;╓═┼#3╔╧:╥!┼;╫(@(╥1╞9┬ [;╒1(15))4╘4╠╚$5615)9
  1658. ═5$┴)3─>@4─5,159!3┼2@4╘┴/54╤$#2!┴9&,@(╥0╨,2 [0─6@0╘]-4$╤%5$5,
  1659. ═6:!)3╩!42$6@3$]7╚$)95$4╬#2!╙=&$@86-├#2!╥=',@(#═╔╚$┴/4$4╬+┬╪-
  1660. ═#2╚═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═#2╩@9╘5.15)!3*!1
  1661. ═54535$┼/3─%"3$4═5─%,546@15)23╒*@4%)/0╘5$55)%#0╒├:&]╦92!╠9'@@
  1662. ═(╙ ╨#3╔╠;╓]╨(&╤─82 ┌8╫1┼>'0╠> ╘@8╞5╤(#╔─;╓┘┼#2!╩<╫(@8╓┴╥;╫5╘
  1663. ═#2!╔;╟@-(&╔═<" ┌;&]╧< ╘┌9&]╬92!╥=',-.╞-╘97┴╘(&┴┼>" ╨9" [8╫(-
  1664. ═('1╪=" ╟4╘]-151(24┘'╚$-(3╘═%1* ┌*"<-(&┴┼>" ╨9# ╨#0╘╩+2╘═+2╘═
  1665. ═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+0╘╩╚&1205=)3┬>@0:!,24┘%+╩"@
  1666. ═8:!&04┴.╚$╤!2$╪╬#0╘╩*┬╩@<╘]-1:!54╘5&54╥@34%#4─]3#0╒╨;&]╘<'@@
  1667. ═;6%├(" [4$╤/5*!!╚%!/24┘4╚$┼.╚%@-('!╚82 @.╫531:!42$┼3╚$].1:!%
  1668. ═5─526:!424╒%#2!╠9&$@8╞┼╘<"╤╪(#═╪╚$┼3╚$┼.0╒)%05-%1 ╘@8╟!╠(&,╤
  1669. ═#2!┼;╫(@8╟5╞9╞5╥#2!╙=&$@8╟5╞9╞5╥#2!┬;6─@8╙(-(&┼╬8╥!┬=69╞97(╦
  1670. ═,0╒├,┬!╠9&$@(╥4╤,# ╨,# ╨, ╒├,2!╧<╞$@*&)╒9╞9┼<┬─╠>0╘@<╫1┴("┴┬
  1671. ═=69╞97(╔+'─-('!╠82 @.╓┘%142@5$^@4╘%61:!┴(0╘@/#╨\#0╒╨;&]╘<'─@
  1672. ═;6%├(" [<$╤/5*!!╚%!/24┘4╚$┼.╚%─┌╚%-)35!,15*@04┘$╚$┘%0╘534╘%2
  1673. ═62$-('!╚82 @.╫531:!42$┼3╚$].1:!72$5.╚%┼/5:!*55-4╚$┼.0╒)%05-%
  1674. ═╚'─-(&╤─82!┬:71╨+'@@.╘)55*!╪╚$1/15-.)╒2@0╘┴!3─=%#2!╧<╞$@*&)╒
  1675. ═9╞9┼<┬─╠>0╘@<╫1┴("┴┬=69╞97(╔+'─-('!╠80╘@/#╨\#0╒├:6┘╔="!═86,@
  1676. ═(#══04-23┌!43┌!)3─┼424%,25╔%╚%1(1:!#3╒5.5$52#2!╠9&$@73$@.╘18
  1677. ═╚$]2╚$19#2!╠<╫(-(&5╧<┬ ├)&9╞(#╠╚;─]4╚%173╥=3╚$-/35!,14╒%3┼0╔
  1678. ═#2!┴9&,@(╥0╨,2 [8: ]╚#(╒-┬╒$6"\╥╚$]2╚#(╒-┬╒$62\╥#2 \/#╨@(#═╘
  1679. ═2$6@1%@╧,╩!-04═%4┌!!╚$┘)0╘52╚$╤/3╘═)3─>@3$┼.10╘->'-╘97 @;6%├
  1680. ═(" [;4%#4─^@5$^@5$%+1:!!╚%-415"@24┌@> ╒╪;&]╧<"!╔;╟@-(&%─8╥!─
  1681. ═>0╘@8╞-├(&╨╤#2╩@9$^@5╘6@55-%╚&┼╬>:!/4╩!─97╞@2$5213\-(&┼╞(&─╠
  1682. ═73$@.╓┼&╚%1(1:!&25)35*!#2$%204-415*@25.@04┌@)╓─╟#2!╔;╟─-(&5╠
  1683. ═<╓4-(&1┼>0╘@9╞┼╬#2!╙8╞,@9'@-;#$@/├╪^('!╠;╫1╨>" [84╤705┼3╚%1!
  1684. ═2╘6@0:!35$50╚$┼.╚'@-(&-╨>"!╪,@╘@8╞┘┼('┴╠;╓]╨#2 \/#╨-#7┼╙=&5╨
  1685. ═(&╒┴8╥ @.╫-!346@5$┴)3─<╠╚$)55*!&3╒*@>0╒┘;&]╧<"!╔9┬!╔+%╘╤#2!╔
  1686. ═;╟─-(&5╠<╓4-(&1┼>0╘@8╓╤├(" [=─526:!)35!/4┼1!3┼0┴#2!╞:6╪-(&%─
  1687. ═8╥!─> ╘@8╞-├(&╨╥#2!╔;╟@@(#═┴3%=!65.@24┘#4─5!4╘6@> ╘@<╓)├(&1┘
  1688. ═#2 ^/├╪@<&╤╧='!╪#2!╩;7 @;#,-;#(@/├╪^('!╠;╫1╨>2 [=╘6@3╘┘,6:!)
  1689. ═3─-214%3142@>0╒╠,╥!├<'─@>3(-(&)╬92!┘;&]╧< ╘@/#╨\#0╘╩*┬╚╩╚&┼.
  1690. ═251)04╥@3$┼.1:!315154 ╘-9')┴=╥ ^/├╪@;6]╓92╤╘>#$[>#$@(#══3╒9%
  1691. ═╚%-4549&╚$┼.5$^@6─523┌!004=%#2 ^/├╪@;6]╓92╤╘>#([>#(@(#═╫2$52
  1692. ═1:!)5*!#04┌@0─6@34]$249)140-(#╪^/┬!═;╫9┼+'1┘,3═┘,0╘@/├╪^(&╒╧
  1693. ═=╞4╠='─╥.╫─╥#2 ^/├╪@<╓5╘8╟5╞(#═╬3╒>@5╘6@0╘%.╚$-,3╘)"15*@5$┴%
  1694. ═╚$)51─9%4@╘-('-┼8╥ @.╓╒!2╘6@4╒521:!8,3╤8,@╘@;&1┴('@╥#2!╙8╞,@
  1695. ═>#$-(&)├<╥ ┌8╓]╬= ╘@;&1┴('─╥(#═╔1╩!.3╒0╠╚%-705"@<#&@04┘$╚' ╥
  1696. ═#2!╠9'─@>3$-('-╘82!┘,0╘@<╫1┘('─╥#2!╠9&$@>#$-(&╤─>2!╪,@╘@<╫1┘
  1697. ═('@╤#2!╙=&$@>#(-#2!╙8╞,@>#$@.╓┘/5┌!┴/418#3╔├;╓┘╘('-╘82!─> ╘@
  1698. ═;&1╪('@╤(#═╨552@6#&@24┘43┌!╪+*!.3╒>@5╘6@0╘%.╚%1205-(╚'@╤#0╒├
  1699. ═;╓╤╒;6╪@;&1┴('@╤(#═╞24┘$╚%1(1:!&25)35*!#3╘╤534┌@1─]2╚'@-(&╤╙
  1700. ═<┬ @.╥┴╘2$┼3╚$-!3╩!"1:!-041%╚$╒50╘┬@1─%35$52(2─-(&╤╙<┬ @.╫1(
  1701. ═15)%╚$%21:!8,2\╪╚#$╥.*!"651%╚$),3╘-+4╨╘@;'-╥(" [=╘┴)0╘┬@345!
  1702. ═3┼.@6#$╧,3:@,├4╓╚$)95$6@0─╤/0╘═3#2!╠<╫(-(&)├8╥ ┌979┼;┬ [=╘┼4
  1703. ═2*!!╚%!/4╒-)0─╤%╚$585%)!╚#$╥.*!"651%╚$),3╘-+#2!╠9'─@(╥0╪," [
  1704. ═24:@4╘\╠╚%-%5*!42$6@2$┼'2*!"250-('-╘>2!┬=69╞97(-(&-╠8╨╘┌979┼
  1705. ═;┬!┴9&,@8╟5╞9╞5╥*╙$@.╓%$1*!)3╩!42$6@3┼5-0─52╚$]&╚#(╒-╩!"651%
  1706. ═╚$),3╘-+4╨╘@<╫1┴(&)╒9╞9┼<┬╠╤(#═┴3─2@4╒1/4─6@250┴#0╘@<╓5├#2!╠
  1707. ═9&$@>3(@.╓-!3$-53$%41:!$60╘@<╓)├('─╤#2!┬8╫,@.╞-╧;╟0╥(#═╔4┌!9
  1708. ═,├┘9,3\-(&╤─82!┘,2 [;╒1(15)725-%╚$19/5─╤+5─╥#2!╙8╞,@>3(-.╞-╧
  1709. ═;╟0╥('-╘82!─>0╘@8╓╒╨(&1╪(#═╫2$\╟4┌!"24='15(┌╚$19╚$]2╚$18/╨╘@
  1710. ═8╞-╙('-╘97!╔;╟─@.╓┼&╚$19+*!71:!.145$╚%1/╚%1!2╘6@0─┼'╚%-415!3
  1711. ═╚$┼.╚%─-#7-╘97!╔;╟@@;&1┘('─╤(#═╪╚$┼3╚$%,4─5!1%╞@4╘54╚%1/╚%@╤
  1712. ═#2!╠9&$@8╞┼╘<"╤╪(#═╨3$]4╚%1(1:!&25)35*!03╘┼.5 ╘@;╫)┴("┴┬=69╞
  1713. ═97(╔+'─-('-╘82 ╚8╟5╞9╞5╥*2╤┘#2 ^/├╪@8╓┼╬:70╠9'@@.╓┼.251)04╤)
  1714. ═6─6@5$┴%╚$-/54┘415(-(&-╨>2!┘,@╘@8╞-╙('┴─96-┘(#═─3┌!71:!35$50
  1715. ═╚$9/4┼=!4─13╚$]2╚$)!0╘═705)$4┌!)3╩!┘/╨╘->&┼╬8╫─@/├╪^('┴╙=&5╨
  1716. ═+&┼╬>0╘@<╟1╙#0╒╪9&5├>2 ^/├╪@>'-╘97 ╠9&5┘#2!╥=',-#7-╘97!╔;╟─@
  1717. ═;&1┘('─╤(#═╫14╤,+*!!╚$╤)5%1,1:!215!%5$┼424].╚$┘%5─52╚$┴54┼2@
  1718. ═04┘93╘┘%#2!╠9&$@8╞┼╘<"╤╪#2!╧<╞$@*&)╒9╞9┼<┬─╠>0╘@<╫1┴("┴┬=69╞
  1719. ═97(╔+'─-(#╪^/┬!├:6┘╔="╤─>0╘@8╫!┘('─╥#2!┬8╫,@>61┼8╫─-#7┼╔;╞-┘
  1720. ═(#╪^/┬!┘<╫1┼<"╤╔;╟─-(')╘<╨╘->61┼8╫─@/├╪^('┼╙=&5╨+&1┼>0╘@<╟1╙
  1721. ═#0╘-*┬╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘-*╩!├3$5!3╩!5
  1722. ═4 ╘-8╓╤┼86┘╒<"!╠9&$@=╞╒├<╓(@.╫-7251#2*!#2$%2╚%)/3:!"04-+╚$┼.
  1723. ═#2!┴;╞0@(╥4╤,3$╤,#$╨,2 [1$5&055,5 ╘@<╫1┴('9═8╫-┬#0╘@<╟1╙(" [
  1724. ═0┼┼%(0╘-*┬╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘-*╩!╙3╘╒%
  1725. ═╚%9!4─┼!0─╤%4╨╘-='@╤(&1╙(#$-='─╤(&1╙(#$-='@╥(&1╙(#$-='─╥(&1╙
  1726. ═(#$-<#%╪(&1╙(#$@.╫1(15-%╚$%21:!414╒03╒)!4┼╞@4╒1/4─%'10╒╨,7─@
  1727. ═9',@,2 [=5-%1*!)3╩!03$]45$┼.1┌!42$6@4%)/2─5#5$┼/3@╒╨,╟@@9',@
  1728. ═,0╒╨,╟─@9',@,2 [=$┴%6:!!4─6@2$521:!33┌!42$%4╚%=%#7 ╙>"!─<╥ ╤
  1729. ═(#═$3╘╪╟5*!(059%╚%1/╚%)%0╘%,0╒5,051%╚%1(14╘╬#7 ╙>2!─<╥ ╤#7 ╘
  1730. ═>"!─<╥ ╤(#═╘2$59╚$╒!2╘6@3$┼&1:!%05-9+@╒╨-'─@9',@,0╒╨-7@@9',@
  1731. ═,2 [=╘┴9╚$%21:!93╒6@3$]/2╘┼.1┌!!5*!-1:!,24═%╚%1(050_#7 ╒>2!─
  1732. ═<╥ ╤(#═─3╘╪╟5*!93╒6@5%)54╒2@344_#7 ╓>"!─<╥ ╤#7 ╓>2!─<╥ ╤(#═╚
  1733. ═059)3─>@04┘/5$┴%4╩!#2$┼,1*!705-.)╒2@35╞@241%02╪-<#=╪(&1╙(#$-
  1734. ═<#=┘(&1╙(#$-<#┴╪(&1╙(#$-<#┴┘(&1╙(#$-9'-╪(&1╙(#$@.╓1╙>*!)4┌!4
  1735. ═2$6@24┘#4─5-14┘4╚$9/4╩!23╒1!5$┼.1┌!!4─]53─2@6 ╒─<╫─@9',@,2 [
  1736. ═<╘┼-24╤!4╩!&3╒*@9'-┘+*!─<╫╚-9'-┌(&1╙(#$-<╫@@9',@,2 [=$┴%4╘6@
  1737. ═05)%╚%1(1:!!0╒1504╥@04┘'3$53╚$┼.╚%┬@6:!!3─2@6@╒╙>2!─<╥ ╤#7-┌
  1738. ═(&1╙(#$-=#$@9',@,2 [=$┴%4╘6@05)%╚%53142@24┌@5$┴%╚%)/5$%424].
  1739. ═#70╥(&1╙(#$-=#,@9',@,2 [<╘5%╚%1(1:!!4┼1)0╘╤%╚$9/4╩!-3╒)%╚$1%
  1740. ═5$%)3%,-=#0@9',@,0╒╘-2!─<╥ ╤#70╓(&1╙(#$-=#<@9',@,0╒╘."!─<╥ ╤
  1741. ═#70┘(&1╙(#$-=#$╨(&1╙(#$-83$╤(&1╙(#$@.╫1(15-%╚$%21:!42$6@14╤%
  1742. ═345.5%.@3╘:@5$┴%╚%)/5$%424].╚$╒!5%))6 ╒┬,3(@9',@,2 [>'┼┌#6,╤
  1743. ═,╥!─<╥ ╤#60╥,2!─<╥ ╤(#═╘2$6@3┼5-0─52╚$1%3─]415.@*%)/5╥╤#3╘╤5
  1744. ═34╪╔#64╥,┬!─<╥ ╤#68╥,╥!─<╥ ╤#6<╙,2!─<╥ ╤#6@╙,┬!─<╥ ╤#6─╙,╥!─
  1745. ═<╥ ╤#71┴(&1╙(#$@.╫1(15-%╚$%21:!414╒03╒)!4┼╞@3$]#051)3╘┘3#71┬
  1746. ═(&1╙(#$@.╘9/4╩!54╘6@0┼╞@5$┴%╚%!23╘╔%0╒1)3╘┌@4─]55$┼.10╒╘8╥!─
  1747. ═<╥ ╤#71─(&1╙(#$-=&4@9',@,0╒╘9┬!─<╥ ╤#71╟(&1╙(#$-=&@@9',@,0╒╘
  1748. ═:2!─<╥ ╤#0╘╩+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+2╘═+0╘╩╚'-%
  1749. ═5*!54*!"252@5$%"3$4-#2!─<╥!>(#═├3$5!4╩!43┌!%3─2@3╘:@4$%'10╘@
  1750. ═(" [<╘^@5$┴!5*!404),15.@4╒1!4┼2@3╘┌@0:!004=%╚$)/54┘$05)9#6)╔
  1751. ═=' @;'5╨(#$╓(#╠╤,├┬@94┘44─┼%4┌!&3╒*@> ╘@9&9┬("4╤,# ╨,# ╨, ╘@
  1752. ═9&9┬("4╨,3 ╨,# ╨, ╘@9&9┬("4╨,#$╨,# ╨, ╘@9&9┬("4╨,# ╤,# ╨, ╘@
  1753. ═9&9┬("4╨,# ╨,3 ╨, ╘@9&9┬("4╨,# ╨,#$╨, ╘@9&9┬("4╨,# ╨,# ╤, ╘@
  1754. ═9&9┬("4╨,# ╨,# ╨,0╘@+2╒>#7-╔;┬ @(#═╘04),1:!/1╩!324┘%4╥╥@,3(╨
  1755. ═╚$)95$53#6-╧<╥!┼<74@<╓┼╬*╙$╥." [=$%"3$6@3╘:@0╘]324┘%4╨╘@(" [
  1756. ═8─]42*!/1╩!42$531:!44─┼'╚%1!0─╤%4┌!!4─4-(" @.╘-54┼)%3┼1,6:!3
  1757. ═152@55"@1┼)/3:!┬87-╔8╨╒┌9&┼╓(&5╤=2!├;╫,╦,3(╪(#═─259)4╘┼/3╩!4
  1758. ═04),10╘                                                     
  1759. #    
  1760.  
  1761. END
  1762.  
  1763. =============================================================================
  1764. ─┼╙╔╟╬ ╧╞ ┴ '╥┼┴╠' ╧╨┼╥┴╘╔╬╟ ╙┘╙╘┼═ ╞╧╥ ╘╚┼ 128: ╨┴╥╘ ╔
  1765. BY ├RAIG ┬RUCE  <CSBRUCE@CCNGA.UWATERLOO.CA>
  1766.  
  1767. 0. ╨╥┼╞┴├┼
  1768.  
  1769. ╔ ORIGINALLY PLANNED TO WRITE THIS ENTIRE ARTICLE ALL IN ONE GO, BUT ITS
  1770. SIZE, COMPLEXITY, AND SCOPE OF REQUIRED DESIGN DECISIONS HAVE FORCED ME TO
  1771. SPLIT THIS ARTICLE INTO TWO PIECES.  (╬OT TO MENTION MY OWN POOR TIME
  1772. MANAGEMENT IN WRITING THIS ARTICLE).  ╘HIS PART GIVES AN INTRODUCTION TO WHAT
  1773. ╔ AM TALKING ABOUT AND DISCUSSES, AT AN ABSTRACT LEVEL, HOW THE SYSTEM WILL
  1774. WORK.  ╘HE NEXT PART WILL DIVE INTO ALL OF THE NUTS AND BOLTS OF THE
  1775. LOW-LEVEL DESIGN.
  1776.  
  1777. ┴LSO, THIS ARTICLE MAY BE A BIT TO WEIRD FOR SOME PEOPLE TO GRASP.  ╨LEASE
  1778. BEAR WITH ME.  ╘HIS ARTICLE IS AS MUCH A SCRATCHPAD FOR MY ROUGH IDEAS ABOUT
  1779. THE KIND OF SYSTEM ╔ WANT TO BUILD AS IT IS AN EXPLANATORY ARTICLE.  ┘OU MAY
  1780. NEED A ═ASTER'S DEGREE IN SOFTWARE SYSTEMS TO UNDERSTAND SOME OF THE THINGS ╔
  1781. TALK ABOUT.  ╘HIS ARTICLE MAKES REFERENCES TO THE ┴├┼ OPERATING SYSTEM, WHICH
  1782. IS AVAILABLE VIA ANONYMOUS ╞╘╨ FROM "CCNGA.UWATERLOO.CA".  ┴├┼ IS A
  1783. UNI-TASKING ╧╙ THAT HAS A ╒NIX-LIKE FLAVOR.  (┘EAH, YEAH, YEAH, ╔'M STILL
  1784. WORKING ON THE NEXT RELEASE...).
  1785.  
  1786. ╧NE MORE NOTE ABOUT THE ARTICLE: IT IS WRITTEN IN THE PRESENT TENSE ("IS")
  1787. RATHER THAN THE FUTURE TENSE ("WILL"), SINCE THE PRESENT TENSE IS EASIER TO
  1788. READ AND UNDERSTAND.  ╘HE SYSTEM, HOWEVER, DOES NOT PRESENTLY EXIST AND THE
  1789. DESIGN MAY CHANGE IN MANY WAYS IF THE SYSTEM EVER IS MADE TO EXIST.
  1790.  
  1791. 1. ╔╬╘╥╧─╒├╘╔╧╬
  1792.  
  1793. ╘HE FULL TITLE OF THIS ARTICLE SHOULD BE "─ESIGN OF A ═ULTITASKING ─ISTRIBUTED
  1794. ═ICROKERNEL ╧PERATING ╙YSTEM FOR THE ╟OOD ╧LD '128".  ╞OR PURPOSES OF
  1795. DISCUSSION, WE WILL CALL THE NEW OPERATING SYSTEM "┬╧╙".  ┴ "MULTITASKING"
  1796. OPERATING SYSTEM (╧╙) IS ONE THAT IS ABLE TO EXECUTE MORE THAN ONE "PROCESS"
  1797. "CONCURRENTLY".  ┴ ╨ROCESS IS AN INSTANCE OF A RUNNING PROGRAM.
  1798. "├ONCURRENTLY" MEANS THAT THE PROGRAMS APPEAR TO BE RUNNING AT THE SAME TIME,
  1799. ALTHOUGH IN REALITY THEY ARE NOT, BECAUSE THERE IS ONLY "ONE" PROCESSOR IN THE
  1800. 128 AND IT CAN ONLY DO ONE THING AT A TIME.
  1801.  
  1802. ┴ "DISTRIBUTED" ╧╙ IS ONE THAT RUNS ON A COLLECTION OF INDEPENDENT COMPUTERS
  1803. THAT ARE CONNECTED BY A NETWORK.  ╒NLIKE A "NETWORK" ╧╙, A DISTRIBUTED ╧╙
  1804. MAKES ALL OF THE INDEPENDENT COMPUTERS LOOK LIKE ╧╬┼ BIG COMPUTER.  ╔N
  1805. GENERAL, A DISTRIBUTED SYSTEM, AS COMPARED TO A CENTRALIZED ONE (LIKE ═╙-─╧╙
  1806. OR ╒NIX), GIVES YOU "A HIGHER PERFORMANCE/PRICE RATIO ('MORE BANG FOR THE
  1807. BUCK'), POTENTIALLY INCREASED RELIABILITY AND AVAILABILITY BECAUSE OF PARTIAL
  1808. FAILURE MODES (IF PROTOCOLS ARE IMPLEMENTED CORRECTLY), SHARED RESOURCES,
  1809. INCREMENTAL GROWTH AND ONLINE EXTENSIBILITY, AND [A CLOSER MODELLING OF] THE
  1810. FACT THAT SOME APPLICATIONS ARE INHERENTLY DISTRIBUTED."  ╘HIS IS QUOTED FROM
  1811. MY ╨H.─. THESIS ABOUT DISTRIBUTED SYSTEMS OF POWERFUL WORKSTATIONS.  ╘O US, A
  1812. DISTRIBUTED SYSTEM MEANS INCREASED MODULARITY AND EASE OF CONSTRUCTION,
  1813. SHARING DEVICES LIKE DISK DRIVES AND RESOURCES LIKE MEMORY BETWEEN MULTIPLE
  1814. COMPUTERS, AND THE TRUE PARALLELISM OF RUNNING DIFFERENT PROCESSES ON
  1815. MULTIPLE COMPUTERS AT THE SAME TIME.  ╬OT TO MENTION "COOLNESS".
  1816.  
  1817. ┴ "MICROKERNEL" ╧╙ IS ONE THAT HAS THE SMALLEST KERNEL POSSIBLE BY PUSHING
  1818. HIGHER-LEVEL FUNCTIONALITY (SUCH AS THE FILE SYSTEM) INTO THE DOMAIN OF USER
  1819. PROCESSES.  ╘HE KERNEL ENDS UP BEING SMALL, FAST, AND EASY TO CONSTRUCT
  1820. (RELATIVE TO A MONOLITHIC KERNEL).
  1821.  
  1822. ╙O WHY WOULD WE WANT OUR ╧╙ TO HAVE THE FEATURES OF ═ULTITASKING,
  1823. ─ISTRIBUTED, AND ═ICROKERNEL?  ┬ECAUSE ╔'M DESIGNING IT, AND THAT'S WHAT
  1824. INTERESTS ME.  ╘HE EASE-OF-CONSTRUCTION THING IS IMPORTANT TOO.  ┴NOTHER
  1825. IMPORTANT QUESTION IS "CAN IT BE DONE?".  ╘HE ANSWER IS "YES."  ┴ND IT WILL
  1826. BE DONE, WHENEVER ╔ GET AROUND TO IT (ONE OF THESE LIFETIMES).
  1827.  
  1828. 2. ╟┼╬┼╥┴╠ ─┼╙╔╟╬ ╧╓┼╥╓╔┼╫
  1829.  
  1830. ╘HERE ARE A NUMBER OF HIGH-LEVEL DESIGN DECISIONS THAT MUST BE MADE BEFORE
  1831. GOING INTO A DETAILED DESIGN.  ╘HIS SECTION DISCUSSES THESE DECISIONS.
  1832.  
  1833. 2.1. ╙╨┼├╔┴╠ ├-128 ╞┼┴╘╒╥┼╙
  1834.  
  1835. ╘HE ├-128 HAS A MINUMUM SET OF SPECIAL FEATURES THAT MAKE IT FEASIBLE TO RUN
  1836. A MULTITASKING OPERATING SYSTEM, AS OPPOSED TO EARLIER MACHINES LIKE THE
  1837. ├-64.  ╘HE SIMPLEST SPECIAL FEATURE THAT THE ├128 HAS IS *ENOUGH MEMORY*.  ╘HE
  1838. 64╦ OF THE ├64 JUST ISN'T ENOUGH.  ╘HE 128╦ OF THE ├128 IS JUST BARELY
  1839. ENOUGH. ┼XPANDED INTERNAL MEMORY MAKES THE PROPOSITION EVEN EASIER.
  1840.  
  1841. ╘HE ├-128 ALSO HAS RELOCATABLE ZERO-PAGE AND STACK-PAGE POINTERS.  ╘HIS
  1842. FEATURE ARE ABSOLUTELY ESSENTIAL AND YOU COULD NOT MAKE AN EFFECTIVE
  1843. MULTITASKING ╧╙ FOR ANY 6502 MACHINE WITHOUT IT.  ╔ WONDER IF ├OMMODORE
  1844. THOUGHT ABOUT THIS PROSPECT WHEN DESIGNING THE ══╒ CHIP...
  1845.  
  1846. ╘HE LAST ├-128 FEATURE IS *SPEED*.  ╘HE ├128 HAS A 2 ═╚Z CLOCK SPEED WHEN
  1847. USED WITH THE 80-COLUMN ╓─├ DISPLAY.  ╘HIS IS ENOUGH SPEED, WHEN HARNESSED
  1848. PROPERLY, TO MAKE YOUR APPLICATIONS ZIP ALONG.  ╞OR AN EXAMPLE OF SPEED THAT
  1849. IS NOT HARNESSED PROPERLY, SEE ═ICROSLOTH ╫INDOZE.  ╘HE ╓─├ DISPLAY IS ALSO
  1850. VERY NICE, TOO.  ╧NLY THE ╓─├ DISPLAY SHOULD BE SUPPORTED BY A "REAL" ╧╙, NOT
  1851. THE ╓╔├ DISPLAY.
  1852.  
  1853. 2.2. ╬┼╘╫╧╥╦
  1854.  
  1855. ╘HE ╧╙ SHOULD BE DESIGNED TO RUN ON A SYSTEM OF BETWEEN 1 AND ╬ ├-128'S,
  1856. WHERE ╬ HAS A MAXIMUM OF SOMETHING LIKE 8 OR 16.  ╫E'LL CHOOSE 16 FOR OUR
  1857. SOFTWARE DESIGN.  ╘HE THEORY IS THAT THE STYLE OF OPERATING SYSTEM THAT WE
  1858. ARE PROPOSING MAKES THE STEP BETWEEN 1 AND ╬ ├-128'S A (RELATIVELY) EASY ONE,
  1859. SO WHY NOT GO FOR IT.  ┴LSO, IF ╬ WERE TO BECOME SOME NUMBER LIKE 256 OR
  1860. 65536, THEN WE COULD START KICKING SOME SERIOUS ASS PERFORMANCE-WISE, FOR
  1861. CERTAIN CLASSES OF COMPUTATIONS.  ┴LSO, ╔ HAPPEN TO OWN TWO ├-128'S AND ╔
  1862. HAVE ALREADY CONSTRUCTED A PARALLEL-PORT NETWORK (A ╩EDI'S WEAPON!), SO ╔
  1863. MIGHT AS WELL USE IT.
  1864.  
  1865. ╘HE REQUIRED NETWORK CONNECTS THE USER PORTS OF ├-128'S INTO A BUS.  ╔'M NOT
  1866. COMPLETELY SURE HOW TO CONNECT MORE THAN TWO ├-128'S TO THIS BUS (╔'D
  1867. PROBABLY NEED SOME DIODES OR LOGIC GATES), SO THE INITIAL VERSION OF THIS
  1868. NETWORK HARDWARE WILL HAVE A MAXIMUM OF TWO HOSTS.  ╫E WILL STILL BE CAREFUL
  1869. TO MAKE THE SOFTWARE OF THE SYSTEM EASILY RECONFIGURABLE FOR ANY NUMBER OF
  1870. HOSTS.
  1871.  
  1872. ┘OU WILL NEED TWO APPROPRIATE CONNECTORS AND SOME 14-CONDUCTOR RIBBON CABLE
  1873. TO BUILD THE NETWORK.  ╧NE OF MY CONNECTORS IS A 44-CONDUCTOR CONNECTOR OF
  1874. THE TYPE USED WITH THE ╓╔├-20 EXPANSION PORT THAT ╔ SAWED IN HALF AND THE
  1875. CABLE IS SOME OLD JUNK RIBBON CABLE THAT WAS LYING AROUND THAT ╔ REMOVED SOME
  1876. OF THE CONDUCTORS FROM.  ┴NY OLD JUNK WILL DO.  ┘OU'RE PROBABLY BEST OFF IF
  1877. YOUR CABLE IS LESS THAN SIX FEET LONG (2 METRES).  ╘HE NETWORK IS WIRED UP AS
  1878. FOLLOWS:
  1879.  
  1880. ├128-┴  NAME/PIN                                      PIN/NAME  ├128-┬
  1881.          ╟╬─ <┴>+------------------------------------+<┴> ╟╬─
  1882.         ╞╠┴╟ <┬>+------------------------------------+<8> ╨├2 ***
  1883.          ╨┬0 <├>+------------------------------------+<├> ╨┬0
  1884.          ╨┬1 <─>+------------------------------------+<─> ╨┬1
  1885.          ╨┬2 <┼>+------------------------------------+<┼> ╨┬2
  1886.          ╨┬3 <╞>+------------------------------------+<╞> ╨┬3
  1887.          ╨┬4 <╚>+------------------------------------+<╚> ╨┬4
  1888.          ╨┬5 <╩>+------------------------------------+<╩> ╨┬5
  1889.          ╨┬6 <╦>+------------------------------------+<╦> ╨┬6
  1890.          ╨┬7 <╠>+------------------------------------+<╠> ╨┬7
  1891.          ╨┴2 <═>+------------------------------------+<═> ╨┴2
  1892.          ╟╬─ <╬>+------------------------------------+<╬> ╟╬─
  1893.         ├╬╘2 <6>+------------------------------------+<6> ├╬╘2
  1894.          ╙╨2 <7>+------------------------------------+<7> ╙╨2
  1895.          ╨├2 <8>+------------------------------------+<┬> ╞╠┴╟ ***
  1896.  
  1897. ╚ERE IS THE ├OMMODORE 128 ╒SER ╨ORT WHEN LOOKING AT THE BACK OF THE UNIT:
  1898.  
  1899.                         111
  1900.                123456789012    TOP
  1901.                ------------
  1902.                ┴┬├─┼╞╚╩╦╠═╬    BOTTOM
  1903.  
  1904. ╘HIS GIVES A PARALLEL BUS THAT CAN OPERATE AT A PEAK OF ABOUT 80
  1905. KILO┬┘╘┼╙/SEC WITH A SHIFT-REGISTER SERIAL BUS THROWN IN THAT CAN OPERATE AT
  1906. A PEAK OF ABOUT 21 KILO┬┘╘┼╙/SEC.  ┬OTH COMMUNICATION CHANNELS ARE
  1907. UNI-DIRECTIONAL, SO SOME MEDIA-ACCESS-CONTROL PROTOCOL WILL NEED TO BE
  1908. PROVIDED BY SOFTWARE.  ╘HE PRICE, IN TERMS OF HARDWARE FOR USING THIS
  1909. NETWORK, IS THAT YOU CAN'T USE A MODEM THAT PLUGS INTO THE USER PORT AT THE
  1910. SAME TIME.  ╧F COURSE, ANY SERIOUS USER WILL HAVE A MODEM THAT PLUGS INTO A
  1911. ╒┴╥╘ CARD ANYWAY.
  1912.  
  1913. ┘OU CAN ALSO WRITE YOUR OWN APPLICATIONS FOR THIS NETWORK, SINCE PROGRAMMING
  1914. IT IS QUITE EASY; THE HARDWARE TAKES CARE OF ALL OF THE HANDSHAKING.  ╘O
  1915. BLAST 256 BYTES OVER THE NETWORK FROM ├128-┴ TO ├128-┬, YOU WOULD:
  1916.  
  1917. ├128-┴: SENDER                             ├128-┬: RECEIVER
  1918. ==============                             ================
  1919.   LDA #$╞╞   ;DDR-OUTPUT                     LDA #$00   ;DDR-INPUT
  1920.   STA $──03                                  STA $──03
  1921.   LDY #0                                     LDY #0
  1922. - LDA ─┴╘┴,Y ;GET DATA                     - LDA #$10   ;WAIT FOR DATA
  1923.   STA $──01  ;SEND DATA                    - BIT $──0─
  1924.   LDA #$10   ;WAIT FOR ACK                   BEQ -
  1925. - BIT $──0─                                  LDA $──01  ;RECEIVE DATA/SEND ACK
  1926.   BEQ -                                      STA ─┴╘┴,Y ;STORE DATA
  1927.   INY        ;NEXT                           INY
  1928.   BNE --                                     BNE --
  1929.   RTS                                        RTS
  1930.  
  1931. ╘HESE ROUTINES CAN EVEN BE TWEAKED A LITTLE MORE FOR HIGHER PERFORMANCE.
  1932. ╨ROGRAMMING THE SHIFT REGISTER IS ANALOGOUS TO THE ABOVE.
  1933.  
  1934. ╘HERE IS PROBABLY NO NEED TO DO ERROR CHECKING ON THE DATA TRANSMITTED OVER
  1935. THE NETWORK SINCE THE CABLE SHOULD BE ABOUT AS RELIABLE AS ANY OF THE OTHER
  1936. CABLES HANGING OUT THE BACK OF YOUR COMPUTER (AND NONE OF THEM HAVE ERROR
  1937. CHECKING (EXCEPT MAYBE YOUR MODEM CABLE)).
  1938.  
  1939. 2.3. ╨╥╧├┼╙╙┼╙
  1940.  
  1941. ┴ PROCESS IS A USER PROGRAM THAT IS IN AN ACTIVE STATE OF EXECUTION.  ╔N
  1942. UNI-TASKING OPERATING SYSTEMS LIKE ┴├┼ OR THE ├OMMODORE ╦ERNAL, THERE IS ONLY
  1943. ONE PROCESS IN THE ENTIRE SYSTEM.  ╔N A MULTI-TASKING SYSTEM, THERE ARE, DUH,
  1944. MULTIPLE PROCESSES.  ┼ACH PROCESS EXECUTES AS AN INDEPENDENTLY RUNNING
  1945. PROGRAM, IN ISOLATION, LOGICALLY AS IF IT WERE THE ONLY PROCESS IN THE
  1946. SYSTEM.  ╧R, AS IF THERE WERE ╬ 8502'S AVAILABLE INSIDE OF THE 128 AND ONE OF
  1947. THEM WERE USED TO RUN EACH PROGRAM YOU HAVE LOADED.
  1948.  
  1949. ╔N REALITY, THERE IS ONLY 1 ├╨╒ IN THE 128 (WELL, THAT WE ARE INTERESTED IN
  1950. USING), SO ITS TIME IS DIVIDED UP AND GIVEN OUT IN SMALL CHUNKS TO EXECUTE SO
  1951. MANY INSTRUCTIONS OF EACH PROGRAM BEFORE MOVING ONTO THE NEXT ONE.  ╘HE ACT
  1952. OF CHANGING FROM EXECUTING ONE PROGRAM TO EXECUTING ANOTHER IS CALLED
  1953. "CONTEXT SWITCHING", AND IS A BIT OF A STICKY BUSINESS BECAUSE THERE IS ONLY
  1954. ONE SET OF PROCESSOR REGISTERS, SO THESE MUST BE SAVED AND RESTORED EVERY
  1955. TIME WE SWITCH BETWEEN PROCESSES.  ┼FFECTIVELY, A PROCESS' COMPLETE "STATE"
  1956. MUST BE RESTORED AND SAVED EVERY TIME IT IS ACTIVATED AND DEACTIVATED
  1957. (RESPECTIVELY).  ╙INCE THE 8502 HAS PRECIOUS FEW INTERNAL REGISTERS, CONTEXT
  1958. SWITCHING CAN BE DONE QUITE EFFICIENTLY (UNLIKE WITH SOME ╥╔╙├ PROCESSORS). 
  1959. ╘HE MAXIMUM PERIOD OF TIME BETWEEN CONTEXT SWITCHES IS CALLED THE "QUANTUM"
  1960. TIME.  ╔N OUR SYSTEM, THE QUANTUM IS 1/60 OF A SECOND.  ╔T IS MORE THAN JUST
  1961. A COINCIDENCE THAT THIS PERIOD IS THE SAME AS THE KEYBOARD-SCANNING PERIOD. 
  1962. ─EPENDING ON PRIORITIES AND READY PROCESSES, A NEW OR THE SAME OLD PROCESS
  1963. MAY BE SELECTED FOR EXECUTION AFTER THE CONTEXT SWITCH OF THE 60-╚Z
  1964. INTERRUPT.
  1965.  
  1966. ╙PLITTING THE TIME OF ONE PROCESSOR AMONG ╬ PROCESSES MAY SOUND LIKE WE'RE
  1967. SIMPLY MAKING EACH ONE RUN ╬ TIMES SLOWER, WHICH MAY BE UNBEARABLY SLOW, BUT
  1968. THAT IS NOT GENERALLY THE CASE.  ╧NE THING THAT A ├╨╒ SPENDS A LOT OF ITS
  1969. TIME DOING IS *WAITING*.  ┼XECUTING INSTRUCTIONS OF A PROGRAM REQUIRES THE
  1970. FULL ATTENTION OF THE ├╨╒, BUT WAITING REQUIRES ABSOLUTELY NO ├╨╒ ATTENTION. 
  1971. ┴S AN EXAMPLE, YOUR SPEEDY COMPUTER SPENDS A LOT OF ITS TIME WAITING FOR ITS
  1972. SLOW-AS-MOLASSES-LAUNCHING-INTO-ORBIT USER TO TYPE A KEY.  ╔F WE WERE TO PUT
  1973. THE PROCESS THAT ASKS THE ╧╙ FOR A KEYSTROKE INTO A STATE OF SUSPENDED
  1974. ANIMATION, THEN THE ├╨╒ TIME THAT PROCESS WOULD HAVE CONSUMED IN A
  1975. BUSY-WAITING LOOP CAN BE BETTER SPENT ON EXECUTING THE OTHER PROCESSES THAT
  1976. ARE "READY" TO EXECUTE.  ╔N PRACTICE, MANY PROCESSES SPEND A LOT OF THEIR
  1977. TIME WAITING, SO "MULTI-PROGRAMMING" IS A BIG WIN.
  1978.  
  1979. ╘HERE ARE A NUMBER OF THINGS OTHER THAN KEYSTROKES THAT PROCESSES MAY WAIT
  1980. FOR IN OUR ENVISIONED SYSTEM: MODEM CHARACTERS, DISK DRIVE OPERATIONS (IF
  1981. THEY ARE CUSTOM-PROGRAMMED CORRECTLY), MOUSE & JOYSTICK MOVEMENTS, REAL-TIME
  1982. DELAYS, AND INTERACTIONS WITH OTHER PROCESSES.  ╘HE ╧╙ PROVIDES FACILITIES
  1983. FOR PROCESSES TO COMMUNICATE WITH ONE ANOTHER WHEN THEY CANNOT PERFORM SOME
  1984. OPERATION IN ISOLATION (I.E., WHEN THEY BECOME LONELY).
  1985.  
  1986. ┴ PROCESS HAS THE FOLLOWING THINGS: A PROGRAM LOADED INTO THE INTERNAL MEMORY
  1987. OF THE 128, ITS OWN ZERO PAGE AND PROCESSOR STACK PAGE, AND THE GLOBAL
  1988. VARIABLES OF ITS PROGRAM.  ┴ PROCESS CAN ALSO OWN "FAR" MEMORY (BELOW) AND
  1989. VARIOUS OTHER RESOURCES OF SERVERS THROUGHOUT THE DISTRIBUTED SYSTEM.  ╘HE
  1990. PROCESS IS THE UNIT OF OWNERSHIP, AS WELL AS EXECUTION.  ╨ROCESSES ALSO HAVE
  1991. PRIORITIES THAT DETERMINE HOW MUCH EXECUTION TIME THEY ARE TO BE GIVEN
  1992. RELATIVE TO OTHER PROCESSES IN THE SYSTEM.
  1993.  
  1994. ╨ROCESSES ARE ALLOCATED MEMORY AT THE TIME OF STARTUP AT A RANDOM LOCATION ON
  1995. SOME RANDOM BANK OF INTERNAL MEMORY ON THE 128.  ╘HE BIGGEST CHALLENGE HERE
  1996. IS TO RELOCATE THE USER PROGRAM TO EXECUTE AT THE CHOSEN ADDRESS.  ╘HE KERNEL
  1997. INTERFACE IS AVAILABLE TO PROGRAMS ON ALL INTERNAL BANKS OF MEMORY.
  1998.  
  1999. 2.4. ┴╨╨╠╔├┴╘╔╧╬ ╨╥╧╟╥┴═ ╔╬╘┼╥╞┴├┼
  2000.  
  2001. ╘O TAKE ADVANTAGE OF EXISTING SOFTWARE, WE WOULD LIKE OUR ╧╙ TO PROVIDE AN
  2002. APPLICATION-PROGRAM INTERFACE (┴╨╔) THAT IS IDENTICAL TO THAT OF THE
  2003. ┴├┼-128/64 OPERATING SYSTEM.  ╔N FACT, THIS IS THE *REAL* REASON WHY ┴├┼ WAS
  2004. DEVELOPED -- AS A STEPPING STONE TOWARD A REAL OPERATING SYSTEM.  ╘HE ┴├┼
  2005. ╨ROGRAMMER'S ╥EFERENCE ╟UIDE, WHICH DESCRIBES THE ┴╨╔, IS AVAILABLE FROM
  2006. "CCNGA.UWATERLOO.CA".
  2007.  
  2008. ╙OME USEFUL SOFTWARE ALREADY EXISTS FOR ┴├┼, AND ┴├┼ HAS A WELL-DEFINIED
  2009. INTERFACE AND WELL-BEHAVED PROGRAMS.  ╘HE ┴├┼ INTERFACE MAY NEED TO EVOLVE A
  2010. LITTLE TOO.  ╘HE ULTIMATE GOAL WOULD BE TO HAVE THE SAME ┴╨╔ FOR BOTH SYSTEMS
  2011. SO YOU COULD RUN SOFTWARE WITH THE MORE FUNCTIONAL ┬╧╙ IF YOU HAVE A ├128 AND
  2012. 80-COLUMN MONITOR, OR YOU COULD USE THE LESS FUNCTIONAL ┴├┼ IF YOU DIDN'T
  2013. HAVE ALL THIS HARDWARE.
  2014.  
  2015. ╘HE SOFTWARE WOULDN'T BE "BINARY-IDENTICAL" SINCE THE OPERATING SYSTEMS
  2016. PROVIDE QUITE DIFFERENT PROGRAM ENVIRONMENTS AND REQUIREMENTS, BUT THE TWO
  2017. SYSTEMS SHOULD BE APPLICATION-SOURCE-CODE COMPATIBLE.
  2018.  
  2019. ┬ECAUSE OF THE VAST DIFFERENCES BETWEEN A MICROKERNEL AND A MONOLITHIC
  2020. KERNEL, ALL OF THE ┴├┼ SYSTEM CALLS WOULD BE REDIRECTED TO USER-LIBRARY CALLS
  2021. IN ┬╧╙. ╘HIS USER LIBRARY WOULD THEN CARRY OUT THE OPERATIONS ACCESSING
  2022. WHATEVER SYSTEM SERVICES ARE NEEDED.
  2023.  
  2024. 2.5. ═┼═╧╥┘ ═┴╬┴╟┼═┼╬╘
  2025.  
  2026. ╘HE MEMORY MANAGEMENT OF ┬╧╙ IS ANALOGOUS TO THAT OF ┴├┼.  ╘HERE ARE TWO
  2027. DIFFERENT CLASSES OF MEMORY: NEAR AND FAR.  ╬EAR MEMORY IS ON THE SAME BANK
  2028. AS A PROGRAM AND CAN BE ACCESSED DIRECTLY BY PROCESSOR INSTRUCTIONS.  ╞AR
  2029. MEMORY CAN ONLY BE ACCESSED THROUGH THE KERNEL BY THE SPECIAL KERNEL CALLS
  2030. ╞ETCH AND ╙TASH AND MUST BE SPECIALLY ALLOCATED TO A PROCESS BY THE OPERATING
  2031. SYSTEM. ╬OTE THAT NEAR MEMORY IS CONSIDERED A SUB-CLASS OF FAR MEMORY; THE
  2032. FAR-MEMORY PRIMITIVES CAN BE USED TO ACCESS NEAR MEMORY.
  2033.  
  2034. ╧NLY THE BASIC MEMORY-ACCESSING CODE IS PROVIDED BY THE KERNEL; HIGHER-LEVEL
  2035. MEMORY MANAGEMENT, SUCH AS DYNAMIC MEMORY ALLOCATION AND DEALLOCATION, IS
  2036. HANDLED BY THE ═EMORY ╙ERVER (BELOW).
  2037.  
  2038. ╒NLIKE ┴├┼, ┬╧╙ PROVIDES THE FUNDAMENTAL CONCEPT OF "DISTRIBUTED MEMORY". 
  2039. ╘HE ╞ETCH AND ╙TASH PRIMITIVES CAN ALSO ACCESS THE MEMORY OF A REMOTE MACHINE
  2040. IN A COMPLETELY USER-TRANSPARENT WAY.  ╘HUS, A FAR-MEMORY POINTER CAN BE
  2041. PASSED BETWEEN PROCESSES ON DIFFERENT MACHINES, AND THE MEMORY THAT THE
  2042. POINTER REFERS TO CAN BE READ AND WRITTEN WITH EQUAL PROGRAMMING BY BOTH
  2043. PROCESSES. ╘HIS FEATURE CAN BE DANGEROUS WITHOUT A SYNCHRONIZATION MECHANISM,
  2044. SO THIS MEMORY SHARING IS INTENDED TO BE USED ONLY WITH THE COMMUNICATION
  2045. MECHANISM.
  2046.  
  2047. ╘HERE SHOULD NOT BE AN UNACCEPTABLE OVERHEAD IN ACCESSING REMOTE MEMORY ON
  2048. THE 128 (LIKE HOW THERE WOULD BE WITH BIGGER COMPUTERS) BECAUSE FAR-MEMORY
  2049. FETCHING FOR LOCAL MEMORY IS QUITE EXPENSIVE ANYWAYS (RELATIVE TO NEAR
  2050. MEMORY), SO AN APPLICATION WILL OPTIMIZE ITS FAR MEMORY ACCESSING, AND THE
  2051. NECESSARY INTERRUPT HANDLING ON THE REMOTE MACHINE CAN BE DONE WITH VERY
  2052. LITTLE LATENCY BECAUSE OF THE "RESPONSIVENESS" OF THE 6502 PROCESSOR DESIGN.
  2053.  
  2054. 2.6. ├╧══╒╬╔├┴╘╔╧╬
  2055.  
  2056. ╔N THE TYPE OF SYSTEM THAT IS ENVISIONED, PROCESSES ARE NOT STRICTLY
  2057. INDEPENDENT AND COMPETITIVE; MANY MUST COOPERATE AND COMUNICATE TO GET WORK
  2058. DONE.  ╘O FACILITIATE THIS INTERPROCESS COMMUNICATION (╔╨├), A PARTICULAR
  2059. ORGANIZATION IS CHOSEN: THE ╥EMOTE ╨ROCEDURE ├ALL (╥╨├) PARADIGM.  ╥╨├ IS A
  2060. MESSAGE-PASSING SCHEME THAT IS USED WITH THE HEAVILY HYPED ├LIENT/╙ERVER
  2061. SYSTEM ARCHITECTURE MODEL.  ╔T REFLECTS THE IMPLICIT OPERATIONS THAT TAKE
  2062. PLACE WHEN YOU CALL A LOCAL PROCEDURE (A SUBROUTINE): THE CALL, THE ENTRY,
  2063. THE PROCESSING, AND THE RETURN.  ╘HE KERNEL PROVIDES THREE PRIMITIVES FOR
  2064. ╥╨├:
  2065.  
  2066. ╙END( PROCESS╔D, REQUEST┬UFFER, REQ╠ENGTH, REPLY┬UFFER, MAX╥EP╠ENGTH ) : ERR;
  2067.  
  2068. ╥ECEIVE( ) : PROCESS╔D, REQUEST┬UFFER, REQ╠ENGTH, REPLY┬UFFER, MAX╥EP╠ENGTH;
  2069.  
  2070. ╥EPLY( PROCESS╔D ) : ERR;
  2071.  
  2072. ╙END() IS USED TO TRANSMIT A MESSAGE TO A REMOTE PROCESS AND GET BACK A REPLY
  2073. MESSAGE.  ╘HE SENDING PROCESS SUSPENDS ITS EXECUTION WHILE IT IS WAITING FOR
  2074. REMOTE PROCESS TO EXECUTE ITS REQUEST.  ┴ MESSAGE CONSISTS OF AN ARBITRARY
  2075. SEQUENCE OF BYTES WHOSE MEANING IS COMPLETELY DEFINED BY THE USER.  ╘HE
  2076. MESSAGE CONTENTS ARE STORED IN A BUFFER (HUNK OF MEMORY) BEFORE SENDING, AND
  2077. A LENGTH IS SPECIFIED AT THE TIME OF SENDING.  ┴ BUFFER TO RECEIVE THE REPLY
  2078. MESSAGE MUST ALSO BE ALLOCATED BY THE SENDER AND SPECIFIED AT THE TIME OF
  2079. SENDING.  ╘O SAVE US FROM THE OVERHEAD OF COPYING MESSAGE CONTENTS TO AND FRO
  2080. UNNECESSARILY, ONLY POINTERS TO THE BUFFERS ARE PASSED AROUND AND THE FAR
  2081. MEMORY PRIMITIVES ARE USED TO ACCESS MESSAGE CONTENTS.  ╘HIS ALSO WORKS
  2082. ACROSS MACHINE BOUNDARIES BECAUSE OF THE DISTRIBUTED-MEMORY MECHANISM
  2083. DESCRIBED ABOVE.
  2084.  
  2085. ╥ECEIVE() IS USED TO RECEIVE A MESSAGE TRANSMITTED BY A REMOTE PROCESS TO THE
  2086. CURRENT PROCESS.  ╘HE RECEIVER BLOCKS UNTIL ANOTHER PROCESS DOES A
  2087. CORRESPONDING ╙END() OPERATION, AND THEN THE REQUEST AND REPLY BUFFER
  2088. POINTERS AND LENGTHS ARE RETURNED.  ╘HE RECEIVER IS EXPECTED TO FETCH THE
  2089. CONTENTS OF THE REQUEST MESSAGE, PROCESS THE REQUEST, PREPARE THE REPLY
  2090. MESSAGE IN THE FAR-MEMORY REPLY BUFFER, AND THEN EXECUTE THE ╥EPLY()
  2091. PRIMITIVE.  ╘HERE ARE NO RESTRICTIONS ON WHAT THE RECEIVER CAN DO BETWEEN
  2092. RECEIVING A MESSAGE FROM A PROCESS AND ISSUING THE CORRESPONDING REPLY
  2093. MESSAGE.  ╙O, IT COULD, FOR EXAMPLE, RECEIVE AND PROCESS MESSAGES FROM OTHER
  2094. PROCESSES UNTIL IT GETS WHAT IT NEEDS, COMPUTE PI TO 10_000 DECIMAL PLACES,
  2095. AND THEN REPLY TO THE PROCESS THAT SENT A MESSAGE TO IT A LONG TIME AGO.
  2096.  
  2097. ╥EPLY() IS USED TO RE-AWAKEN A PROCESS THAT SENT A MESSAGE THAT WAS
  2098. ╥ECEIVE()D BY THE CURRENT PROCESS.  ╘HE CURRENT PROCESS IS EXPECTED TO HAVE
  2099. SET UP THE FAR-MEMORY REPLY BUFFER IN WHATEVER WAY THE SENDING PROCESS
  2100. REQUIRES PRIOR TO ISSUING THE ╥EPLY().
  2101.  
  2102. ╘HE EXPECTED USAGE OF BUFFERS IS FOR THE SENDER TO USE NEAR MEMORY FOR THE
  2103. REQUEST AND REPLY BUFFERS AND ACCESS THEM AS REGULAR NEAR MEMORY TO CONSTRUCT
  2104. AND INTERPRET REQUEST AND REPLY MESSAGES.  ╘HE RECEIVER WILL ACCESS THE
  2105. BUFFERS AS FAR MEMORY (WHICH THEY MAY VERY WELL BE SINCE PROCESSES ARE
  2106. ALLOWED TO EXECUTE ON DIFFERENT BANKS OF INTERNAL MEMORY AND EVEN ON
  2107. DIFFERENT MACHINES), AND MAY WISH TO FETCH PARTS OF MESSAGES INTO NEAR MEMORY
  2108. FOR PROCESSING.  ╘HE USE OF FAR POINTERS MAKES IT SO THAT DATA IS COPIED ONLY
  2109. WHEN NECESSARY.
  2110.  
  2111. ┴ND THAT'S IT.  ┘OU ONLY HAVE THIS ╥╨├ MECHANISM FOR COMMUNICATING WITH OTHER
  2112. PROCESSES AND FOR ALL ╔/╧.  ╫ELL, THAT'S NOT ENTIRELY TRUE; THE ╥╨├ STUFF IS
  2113. HIDDEN BEHIND THE APPLICATION PROGRAM INTERFACE, WHICH PROVIDES SUCH FACADES
  2114. AS THE ╧PEN AND ╥EAD SYSTEM CALLS, AND A VERY-LOW LEVEL INTERRUPT
  2115. NOTIFICATION MECHANISM WHICH A USER PROCESS WILL NOT NORMALLY USE.
  2116.  
  2117. 2.7. ╙┘╙╘┼═ ╙┼╥╓┼╥╙
  2118.  
  2119. ╙INCE ALL THAT USER PROGRAM HAS FOR ╔╨├ AND ╔/╧ IS THE ╥╨├ MECHANISM, A
  2120. NUMBER OF SYSTEM SERVER PROCESSES MUST BE SET UP TO ALLOW A USER PROGRAM TO
  2121. DO ANYTHING USEFUL.  ╘HESE SPECIAL SERVERS EXECUTE AS IF THEY WERE REGULAR
  2122. USER PROGRAMS BUT PROVIDE SERVICE THAT IS NORMALLY IMPLEMENTED DIRECTLY INTO
  2123. THE OPERATING SYSTEM KERNEL.  ╘HERE ARE A NUMBER OF ADVANTAGES AND
  2124. DISADVANTAGES TO ORGANIZING A SYSTEM IN THIS WAY.  ┴ BIG ADVANTAGE IS THAT IT
  2125. IS EASIER TO BUILD A MODULAR SYSTEM LIKE THIS, AND A BIG DISADVANTAGE IS THAT
  2126. YOU LOSE SOME PERFORMANCE TO THE OVERHEAD OF THE ╔╨├ MECHANISM.
  2127.  
  2128. ┴ USEFUL IMPLICATION OF USING SERVERS RATHER THAN HAVING USER PROCESSES
  2129. EXECUTE INSIDE OF THE KERNEL IS MUTUAL EXCLUSION.  ╙ERVERS EFFECTIVELY
  2130. SERIALIZE USER REQUESTS.  ╔.E., USER REQUESTS ARE SERVICED IN ORDER, STRICTLY
  2131. ONE-AT-A-TIME.  ╘HIS IS IMPORTANT BECAUSE SOME OF VARIABLES THAT NEED TO BE
  2132. MANIPULATED IN ORDER TO PROVIDE SERVICE MUST NOT BE MANIPULATED BY MULTIPLE
  2133. PROCESSES SIMULTANEOUSLY OR YOU MAY GET INCONSISTENT RESULTS.  ╘O PROVIDE
  2134. MUTUALLY EXCLUSIVE ACCESS TO SHARED VARIABLES IN A MONOLITHIC SYSTEM, EITHER
  2135. UGLY AND PROBLEMATIC SEMAPHORES MUST BE USED, OR MORE-RESTRICTIVE, SIMPLER
  2136. MECHANISMS LIKE ALLOWING ONLY ONE USER PROCESS TO ENTER THE KERNEL.
  2137.  
  2138. 2.7.1. ╨╥╧├┼╙╙ ╙┼╥╓┼╥
  2139.  
  2140. ╘HIS SERVER IS RESPONSIBLE FOR STARTING AND TERMINATING USER PROCESSES.
  2141. ┬ECAUSE OF THE WAY THAT THE PROCEDURE IS ORGANIZED, THE PROCESS SERVER IS
  2142. ACTUALLY QUITE RESPONSIVE DISPITE ALL OF THE WORK THAT MUST BE DONE IN ORDER
  2143. TO START UP AND TERMINATE A USER PROCESS.
  2144.  
  2145. ╘HE SERVER IS HIGHLY INTEGRATED WITH THE KERNEL, AND IT IS ABLE TO DO THINGS
  2146. THAT REGULAR USER PROCESSES CANNOT (LIKE MANIPULATE KERNEL DATA STRUCTURES),
  2147. BUT IT STILL FUNCTIONS AS AN INDEPENDENT ENTITY, AS A REGULAR USER PROCESS.
  2148. ╔TS CODE IS PHYSICALLY A PART OF THE KERNEL FOR BOOTSTRAPPING PURPOSES, SINCE
  2149. IT CAN HARDLY BE USED TO START ITSELF.
  2150.  
  2151. ╫HEN YOU WISH TO RUN A NEW PROGRAM, A REQUEST MESSAGE IS SENT TO THE PROCESS
  2152. SERVER.  ╘HIS MESSAGE INCLUDES THE FILENAME OF THE PROGRAM TO RUN, THE
  2153. ARGUMENTS TO THE NEW PROGRAM, ENVIRONMENTAL VARIABLES, AND A SYNCHRONOUS/
  2154. ASYNCHRONOUS FLAG.  ╔F YOU WANT TO RUN A SUB-PROCESS SYNCHRONOUSLY, THE
  2155. PROCESS SERVER DOES NOT REPLY TO YOUR REQUEST UNTIL THE NEW PROCESS
  2156. TERMINATES.  ╔F YOU SELECT ASYNCHRONOUS MODE, THE PROCESS SERVER REPLIES TO
  2157. YOUR REQUEST AS SOON AS THE NEW PROCESS IS CREATED.  ┬OTH OF THESE MODES ARE
  2158. QUITE USEFUL IN ╒NIX (ALTHOUGH ╒NIX HAS A MORE COMPLICATED MECHANISM FOR
  2159. PROVIDING THE SERVICE) (THINK "&" AND NO-"&" ON COMMAND LINES), SO THEY ARE
  2160. PROVIDED HERE.
  2161.  
  2162. ╘HE PROCESS SERVER ALLOCATES AND INITIALIZES THE KERNEL DATA STRUCTURES
  2163. NECESSARY FOR PROCESS MANAGEMENT, AND THEN STARTS THE PROCESS RUNNING
  2164. BOOTSTRAPPING CODE IN THE KERNEL.  ╙INCE THIS CODE IS IN THE KERNEL, IT IS
  2165. KNOWN TO BE TRUSTWORTHY.  ╘HE PROCESS THEN BOOTSTRAPS ITSELF BY OPENING THE
  2166. PROGRAM FILE, READING THE MEMORY REQUIREMENTS, ALLOCATING SUFFICIENT MEMORY,
  2167. READING IN THE PROGRAM FILE, RELOCATING THE PROGRAM FOR WHATEVER MEMORY
  2168. ADDRESS IT HAPPENED TO LOAD IN AT (BANK RELOCATION IS NO PROBLEM) AND
  2169. FAR-CALLING THE MAIN ROUTINE (FINALLY).  ╘HE RETURN IS SET UP ON THE STACK TO
  2170. KILL THE PROCESS.
  2171.  
  2172. ╙INCE THE PROCESS BOOTSTRAPS ITSELF, THE PROCESS SERVER'S INVOLVEMENT IN THE
  2173. PROCESS CREATION PROCEDURE IS MINIMAL, AND THE PROCESS SERVER IS READY TO
  2174. PROCESS NEW REQUESTS WITH MINIMAL DELAY (MAXIMAL RESPONSIVENESS).  ╘HIS
  2175. SELF-BOOTSTRAPPING USER PROCESS CONCEPT COMES FROM MY ═ASTER'S ╘HESIS.
  2176. ┴NOTHER ADVANTAGE OF HAVING A PROCESS SERVER IS THAT YOU CAN START A PROCESS
  2177. RUNNING ON ANY MACHINE FROM ANY OTHER MACHINE IN EXACTLY THE SAME WAY YOU
  2178. WOULD START A PROCESS ON THE LOCAL MACHINE; WE HAVE ACHIEVED TRANSPARENTNESS,
  2179. ╨ARK.
  2180.  
  2181. ╘HE PROCESS SERVER ALSO TAKES CARE OF PROCESS DESTRUCTION (EXIT OR KILL) AND
  2182. PROVIDES OTHER LESS-SIGNIFICANT SERVICES, LIKE READING AND SETTING THE
  2183. CURRENT DATE AND TIME.  ╘HE MECHANISM BY WHICH PROCESS DESTRUCTION IS DONE IS
  2184. SIMILAR TO THE SELF-BOOTSTRAPPING IDEA AND IS DISCUSSED, PROBABLY
  2185. INAPPROPRIATELY, IN THE NEXT SECTION.
  2186.  
  2187. ╘HE SERVER IS LOCATED BY HAVING A WELL-KNOWN ADDRESS.  ╘HAT IS, THE PROCESS
  2188. ID IS A CONSTANT AND HARD-CODED INTO CLIENTS.  ╫ELL-KNOWN ADDRESSES ARE SMALL
  2189. INTEGER VALUES, FOR EACH MACHINE (A MACHINE-ID IS ENCODED INTO PROCESS IDS),
  2190. AND THESE INTEGERS ARE INDEXES INTO A SMALL LOOK-UP TABLE WITH THE ACTUAL
  2191. ADDRESSES FOR WELL-KNOWN ADDRESSES, SO THE PROCESS IDS AREN'T PINNED BUT CAN
  2192. BE USED AS IF THEY WERE PINNED.
  2193.  
  2194. 2.7.2. ═┼═╧╥┘ ╙┼╥╓┼╥
  2195.  
  2196. ╘HE MEMORY SERVER HANDLES THE DYNAMIC ALLOCATION AND DEALLOCATION OF FAR
  2197. MEMORY.  ╘HE CLIENT SPECIFIES IN THE REQUEST MESSAGE THE EXACT TYPES OF
  2198. MEMORY THAT IT CAN USE, AND THE SERVER GETS THE MEMORY, SETS THE OWNERSHIP TO
  2199. THE PROCESS, AND RETURNS A POINTER.  ─EALLOCATION OF SOME OF THE MEMORY OWNED
  2200. BY A PROCESS IS HANDLED EASILY.
  2201.  
  2202. ╘HERE IS ALSO A CALL THAT DEALLOCATES ALL MEMORY OWNED BY A CERTAIN USER
  2203. PROCESS.  ╘HIS CALL IS NORMALLY ONLY CALLED BY THE PROCESS SERVER*, SINCE THE
  2204. MEMORY OF THE USER PROGRAM IS BE DEALLOCATED ALONG WITH THE REST OF THE
  2205. PROCESS' MEMORY.  ┴ RECORD IS KEPT INTERNALLY FOR EACH PROCESS ABOUT WHAT
  2206. TYPES AND BANKS (LATER) OF MEMORY IT HAS USED SO THAT BULK DEALLOCATION CAN
  2207. BE DONE EFFICIENTLY WHEN THE PROCESS EXITS.
  2208.  
  2209. ┴ CLIENT PROCESS CAN ALSO ASK THAT FAR MEMORY BE ALLOCATED ON A REMOTE
  2210. MACHINE.  ╥EMOTE MEMORY IS RELATIVELY SLOW TO ACCESS, BUT IT CAN BE
  2211. CONVENIENT WHEN YOU NEED ╠╧╘╙ OF MEMORY FOR A PROCESS.  ╘HE OBVIOUS WAY TO
  2212. GET AT THIS REMOTE MEMORY IS TO SIMPLY SEND A MESSAGE DIRECTLY TO THE REMOTE
  2213. MEMORY SERVER OF THE MACHINE YOU WANT TO ALLOCATE MEMORY ON, AND THIS DOES
  2214. INDEED WORK, SO THIS IS WHAT WE WILL DO.  ┬UT, THIS DOESN'T RECORD THE FACT
  2215. THAT YOU HAVE ALLOCATED MEMORY ON A FAR MACHINE BY ITSELF, AND WE DON'T WANT
  2216. TO WASTE ANY EFFORT IN FREEING ALL OF THE MEMORY, BOTH LOCAL AND REMOTE, THAT
  2217. A PROCESS OWNS WHEN IT TERMINATES; I.E., WE DON'T WANT TO SEND DEALLOCATION
  2218. REQUESTS TO ALL REMOTE MEMORY SERVERS JUST TO BE SURE.
  2219.  
  2220. ╘HERE ARE A FEW ALTERNATIVES FOR SOLVING THIS PROBLEM, BUT ╔ THINK THIS IS A
  2221. GOOD PLACE FOR A QUICK-AND-DIRTY HACK.  ╫HENEVER A USER PROCESS SENDS A
  2222. MESSAGE TO A MEMORY SERVER (BOTH LOCAL OR REMOTE, FOR WHATEVER REASON),
  2223. THROUGH THE MEMORY SERVERS' WELL-KNOWN ADDRESSES, THE BIT CORRESPONDING TO
  2224. THE MACHINE NUMBER (0-15) IN A SPECIAL 16-BIT FIELD OF THE SENDER'S PROCESS
  2225. CONTROL BLOCK IS SET.  ╘HEN, WHEN THE PROCESS TERMINATES, THE TERMINATION
  2226. PROCEDURE (NEXT) PEEKS AT THIS SPECIAL FIELD AND SENDS FREE-ALL MESSAGES TO
  2227. ALL REMOTE MEMORY SERVERS THAT THE PROCESS IN QUESTION HAS INTERACTED WITH.
  2228. ╘HIS INSURES THAT ALL MEMORY IN THE ENTIRE DISTRIBUTED SYSTEM THAT IS
  2229. ALLOCATED TO A PROCESS IS TIDIED UP WHEN THE PROCESS TERMINATES.  ╠IKE THE
  2230. PROCESS SERVER, THE MEMORY SERVER IS INTEGRATED WITH THE KERNEL.
  2231.  
  2232. ═╧╥┼ ╨╥╧├┼╙╙ ╘┼╥═╔╬┴╘╔╧╬
  2233.  
  2234. ├OME TO THINK OF IT, ╔ SHOULD TALK MORE ABOUT PROCESS TERMINATION.  ╘HE BEST
  2235. IDEA WOULD PROBABLY BE FOR A USER PROCESS TO TERMINATE ITSELF, IN THE SAME
  2236. WAY THAT IT BOOTSTRAPS ITSELF.  ┴ TERMINATION MESSAGE IS SENT BY A CLIENT
  2237. PROCESS THAT WANTS TO KILL SOMEONE TO THE PROCESS SERVER.  ╔T IS A VALID
  2238. SITUATION FOR A PROCESS TO COMMIT SUICIDE.  ╘HE TERMINATION MESSAGE INCLUDES
  2239. THE PROCESS ID TO BE TERMINATED AND THE EXIT CODE FOR THE TERMINATION.
  2240.  
  2241. ╘HE PROCESS SERVER THEN SUSPENDS THE DOOMED PROCESS' EXECUTION AND RIGS THE
  2242. PROCESS' CONTEXT SO THAT THE NEXT THING IT EXECUTES IS THE PROCESS SHUTDOWN
  2243. CODE INSIDE OF THE KERNEL.  ╘HIS SHUTDOWN CODE CLOSES ALL OF THE FILES THAT
  2244. THE PROCESS HAS OPENED THROUGH THE STANDARD LIBRARY CALLS (AND OTHER SERVER-
  2245. RESOURCES HELD), DEALLOCATES ALL MEMORY HELD BY THE PROCESS, MAYBE DOES SOME
  2246. OTHER CLEANUP WORK, AND THEN SENDS A SPECIAL MESSAGE TO THE PROCESS SERVER TO
  2247. REMOVE THE PROCESS CONTROL BLOCK.  ╘HE PROCESS SERVER WILL ONLY ACCEPT THIS
  2248. SPECIAL MESSAGE FROM THE PROCESS THAT IS TERMINATING AFTER THE FIRST PHASE OF
  2249. THE PROCESS SHUTDOWN HAS BEEN COMPLETED, TO INSURE A PROPER TERMINATION.  ╘HE
  2250. PROCESS CONTROL BLOCK IS THEN DEALLOCATED AND MAY BE USED AGAIN.  ╘HE PROCESS
  2251. SERVER IS THE ONLY PROCESS THAT IS ALLOWED TO MANIPULATE PROCESS CONTROL
  2252. BLOCKS.
  2253.  
  2254. ├OME TO THINK OF IT, THERE IS A SLIGHT PROBLEM WITH PROCESS INITIALIZATION:
  2255. GETTING A COPY OF THE ARGUMENTS AND ENVIRONMENTAL VARIABLES FOR AN
  2256. ASYNCHRONOUSLY STARTED NEW PROCESS.  ╫E DON'T WANT THE SENDER TO CONTINUE
  2257. BEFORE THE NEW PROCESS HAS HAD A CHANCE TO MAKE A COPY OF THE ARGUMENTS AND
  2258. ENVIRONMENT, SO WE WILL RIG THINGS SO THAT IT IS THE NEWLY STARTED PROCESS
  2259. THAT SENDS THE REPLY MESSAGE BACK TO THE PARENT PROCESS.  ┴NOTHER DIRTY HACK.
  2260.  
  2261. 2.7.3. ╞╔╠┼ ╙┼╥╓┼╥╙
  2262.  
  2263. ┼ACH DISK DRIVE IN THE SYSTEM HAS A SPECIAL SERVER THAT PROVIDES AN INTERFACE
  2264. FOR EXECUTING ╧PEN, ╥EAD, ╫RITE, ├LOSE, AND A NUMBER OF OTHER COMMON FILE
  2265. OPERATIONS.  ┴ BIG PROBLEM WITH DISTRIBUTED OPERATING SYSTEMS IS RESOURCE
  2266. RECLAMATION FOR PROCESSES THAT DIE.  ╘HERE ARE A FEW WAYS TO PROVIDE THIS,
  2267. AND EACH HAS IMPLICATIONS ABOUT THE OVERALL DESIGN OF A SERVER.
  2268.  
  2269. ╧NE POSSIBILITY IS TO HAVE "STATELESS SERVERS".  ╔N OTHER WORDS, EACH SERVER
  2270. DOES NOT KEEP TRACK OF, FOR EXAMPLE, WHICH FILES A PROCESS HAS OPEN OR THE
  2271. CURRENT FILE POSITIONS.  ┼ACH TIME A READ REQUEST COMES IN, THE SERVER OPENS
  2272. THE FILE TO BE USED, POSITIONS TO THE SECTION OF THE FILE, PERFORMS THE
  2273. OPERATION, AND CLOSES THE FILE AGAIN.  ╘HIS SOUNDS LIKE A LOT OF WORK, BUT
  2274. SOME INTELLIGENT CACHING MAKES IT WORK EFFICIENTLY.  ┴ND IF A USER PROCESS
  2275. DIES WITHOUT CLOSING ALL OF ITS FILES, IT DOESN'T MATTER SINCE THE FILES WILL
  2276. BE CLOSED ANYWAY, LOGICALLY AT THE COMPLETION OF EACH OPERATION.  ┬UT, THIS
  2277. APPROACH DOESN'T REALLY WORK WELL WITH ├OMMODORE-─╧╙, WHICH WE WILL BE USING
  2278. FOR DEVICES FOR WHICH WE DON'T HAVE A CUSTOM DEVICE DRIVER, SO WE WON'T USE
  2279. IT.
  2280.  
  2281. ┴NOTHER POSSIBILITY IS TO HAVE "SEMI-STATE" OR "ACKNOWLEDGEMENTLESS" SERVERS
  2282. (MY OWN INVENTION).  ╚ERE, THE SERVER KEEPS TRACK OF, FOR EXAMPLE, WHICH
  2283. FILES ARE OPEN BUT DOESN'T KEEP THE FILE POSITION.  ╫HEN A REQUEST COMES IN,
  2284. THE ALREADY-OPENED FILE IS POSITIONED ACCORDING TO THE REQUEST AND THE FILE
  2285. OPERATION TAKES PLACE.  ╔F A CLIENT DIES UNEXPECTEDLY, THE OPEN FILE CONTROL
  2286. BLOCK (╞├┬) IS LEFT BEHIND, BUT THE ╞├┬ WILL BE CLOSED AND REUSED AFTER A
  2287. CERTAIN PERIOD OF TIME.  ╔F THE CLIENT ACTUALLY HASN'T DIED, THEN THE
  2288. SITUATION WILL BE DETECTED (THROUGH DETAILS NOT EXPLAINED HERE) AND THE FILE
  2289. WILL BE REOPENED AS IF NOTHING HAS HAPPENED.  ╧THER CONTINGENCIES LIKE A DEAD
  2290. PROCESS' NAME BEING REUSED ARE HANDLED TOO.  ┴ND THE MODEL WORKS WELL WITH AN
  2291. UNRELIABLE COMMUNICATION SERVICE.  ┬UT, AGAIN, THIS DOESN'T MODEL THE
  2292. ├OMMODORE-─╧╙ VERY WELL.
  2293.  
  2294. ╘HE FINAL DESIGN CONSIDERED IS TO HAVE A REGISTRY OF SERVERS THAT THAT A
  2295. PROCESS HAS RESOURCES CURRENTLY ALLOCATED ON BE ASSOCIATED WITH EACH PROCESS.
  2296. ╫HEN A CLIENT MAKES AN OPEN REQUEST TO THE SERVER (OR SOME EQUIVALENT
  2297. RESOURCE-GRABBING OPERATION), THE SERVER CHECKS TO SEE IF THE CLIENT IS
  2298. CURRENTLY HOLDING ANY OTHER OF THE SERVER'S RESOURCES.  ╔F SO, THEN THE
  2299. REQUEST IS PROCESSES NORMALLY.  ╔F NOT, THEN THE SERVER (OR SOME AGENT ON THE
  2300. SERVER'S BEHALF) SENDS A MESSAGE TO THE PROCESS SERVER ON THE CLIENT'S
  2301. MACHINE TELLING THE PROCESS SERVER TO RECORD THE FACT THAT THE CLIENT IS (OR
  2302. MAY BE) HOLDING SOME OF THE SERVER'S RESOURCES.  ╘HE PROCESS SERVER RECORDS
  2303. THE SERVER'S PROCESS ID IN THE PROCESS CONTROL BLOCK OF THE CLIENT, AND WHEN
  2304. THE CLIENT TERMINATES, IT WILL SEND A STANDARD "RELEASE ALL OF THE RESOURCES
  2305. THAT ╔ AM (MAY BE) HOLDING ON THIS SERVER" TO THE SERVER AS PART OF THE
  2306. CLIENT'S SHUTDOWN PROCEDURE.  ┴LL OF THE CLIENT'S OPEN FILES WILL BE CLOSED,
  2307. ETC.
  2308.  
  2309. ╔N THIS "REGISTRY" DESIGN, SERVERS CAN BE COMPLETELY "STATEFUL", E.G., THEY
  2310. WOULD CONTAIN BOTH AN OPEN FILE ENTRY AND THE FILE POSITION INFORMATION, AND
  2311. FILES WOULD ALWAYS OPEN AND CLOSE WHEN WE INTUITIVELY EXPECT THEM TO.  ╔T IS
  2312. ASSUMED THAT THE COMMUNICATION MECHANISM IS RELIABLE, WHICH IT IS HERE.  ╘HIS
  2313. MECHANISM *DOES* MODEL ├OMMODORE-─╧╙ WELL.  ╔N FACT, THIS IDEA IS SO NICE
  2314. THAT ╔ MAY REDESIGN THE MEMORY ALLOCATION RECOVERY MECHANISM TO USE THIS. 
  2315. ╘HERE IS A SLIGHT POSSIBILITY OF A "RACE CONDITION" IN THIS MECHANISM, BUT
  2316. NOTHING BAD CAN HAPPEN BECAUSE OF IT.  (╘HIS IS JUST A NOTE TO MYSELF: MAKE
  2317. IT SO THAT IF A PROCESS IS KILLED WHILE IT IS RECEIVE- OR REPLY-BLOCKED, THEN
  2318. IGNORE THE REPLY FROM THE SERVER IF THE PROCESS ID IS REUSED; DAMN, THERE'S
  2319. STILL A POTENTIAL PROBLEM; ╔'LL HAVE TO FIGURE IT OUT LATER; ALSO WATCH OUT
  2320. FOR A DISTRIBUTED DEADLOCK ON THE ╨├┬ LIST).
  2321.  
  2322. ╙O, OUR SERVER SUPPORTS THE REGULAR FILE OPERATIONS AND IMPLEMENTS THEM IN
  2323. PRETTY MUCH THE EXPECTED WAY, SINCE IT IS A "STATEFUL" SERVER.  ╘HE MAIN LOOP
  2324. OF THE SERVER ACCEPTS A REQUEST, DETERMINES WHICH TYPE IT IS, EXTRACTS THE
  2325. ARGUMENTS, CALLS THE APPROPRIATE LOCAL PROCEDURE, PREPARES THE REPLY MESSAGE,
  2326. REPLIES, AND GOES BACK TO THE TOP OF THE LOOP.  ┼ACH OPENED FILE IS
  2327. IDENTIFIED BY A USER PROCESS BY A FILE CONTROL BLOCK NUMBER THAT HAS MEANING
  2328. INSIDE OF THE SERVER, AS PER USUAL.  ┬UT, UNLIKE WITH ┴├┼, WE NEED A SPECIAL
  2329. "─UP" OPERATION FOR PASSING OPEN FILES TO CHILDREN.  ─UP INCREMENTS THE
  2330. "REFERENCE COUNT" OF A ╞├┬, AND THE REFERENCE COUNT IS DECREMENTED EVERY TIME
  2331. A CLOSE OPERATION TAKES PLACE.  ┴ FILE WILL ONLY BE "REALLY" CLOSED WHEN THE
  2332. REFERENCE COUNT REACHES ZERO.  ╧UR SYSTEM WILL NOT IMPLEMENT ANY SECURITY AT
  2333. THIS TIME.
  2334.  
  2335. ┬ECAUSE OF THE ABSTRACTION OF SENDING FORMATTED MESSAGES TO A SERVER,
  2336. DIFFERENT TYPES OF DISK DRIVES (├OMMODORE-─╧╙, CUSTOM-FLOPPY, RAMDISK) ARE
  2337. ALL DEALT WITH IN EXACTLY THE SAME WAY.  ┴S ONE SLIGHT EXTENSION, WE HAVE TO
  2338. HACK OUR DEVICES (AT LEAST SOME OF THEM) A LITTLE TO BE ABLE TO HANDLE
  2339. "SYMBOLIC LINKS" IN ORDER TO INTEGRATE WELL WITH THE ╨REFIX ╙ERVER WHICH IS
  2340. DESCRIBED NEXT.
  2341.  
  2342. 2.7.4. ╨╥┼╞╔╪ ╙┼╥╓┼╥
  2343.  
  2344. ╘HE PREFIX SERVER IDEA IS STOLEN FROM THE COMPUTER SCIENCE LITERATURE ABOUT A
  2345. NETWORK OPERATING SYSTEM CALLED "╙PRITE".  ╘HE PREFIX SERVER SIMPLY PROVIDES A
  2346. PATHNAME LOOKUP SERVICE FOR THE PATHNAMES OF DIFFERENT DISK-FILE AND DEVICE
  2347. SERVERS.  ╘HIS IS NEEDED TO PROVIDE A SINGLE, GLOBAL, UNIFIED PATHNAME SPACE
  2348. ON A SYSTEM OF MULTIPLE DISTRIBUTED FILE SERVERS.  ╔T WORKS A LOT LIKE THE
  2349. "MOUNT TABLE" IN ╒NIX.  ╔TS PREFIX TABLE LOOKS SOMETHING LIKE THE FOLLOWING:
  2350.  
  2351. ╨╥┼╞╔╪      ╙┼╥╓┼╥
  2352. ------      ------
  2353. /           <1:RAMDISK>
  2354. /DEV/TTY0   <1:CONSOLE>
  2355. /FD1        <2:FLOPPY1571>
  2356.  
  2357. ┬╘╫, ┬╧╙ USES ╒NIX-STYLE FILENAMES RATHER THAN THE ├REATIVE-═ICRO-─ESIGNS-
  2358. STYLE FILENAMES THAT ┴├┼ USES.
  2359.  
  2360. ╔F AN APPLICATION IS GIVEN AN ABSOLUTE PATHNAME, IT WILL CONSULT THE PREFIX
  2361. SERVER TO RESOLVE IT TO THE PROCESS-ID OF AN ACTUAL SERVER.  ╞OR EXAMPLE, THE
  2362. PATHNAME "/FD1/BOB/FRED" WOULD RESOLVE TO SERVER "<2:FLOPPY1571>", RELATIVE
  2363. PATHNAME "BOB/FRED".  ╨ATHNAME "/" WOULD RESOLVE TO SERVER "<1:RAMDISK>",
  2364. RELATIVE PATHNAME "".
  2365.  
  2366. ╘HE USER PROCESS WOULD THEN CONTACT THE APPROPRIATE SERVER WITH THE RELATIVE
  2367. PATHNAME.  ┴ USER PROCESS CAN ASSUME THAT THE PREFIX TABLE WILL NOT CHANGE
  2368. WHILE THE SYSTEM IS RUNNING, SO SOME INTELLIGENT CACHING CAN BE DONE.  ┴LSO,
  2369. DIRECTORY TOKENS ARE GIVEN OUT FOR EXECUTING A "CHANGE DIRECTORY" OPERATION,
  2370. AND THESE SERVER/TOKEN PAIRS CAN BE USED FOR QUICK RELATIVE PATHNAME
  2371. SEARCHES.  ┴ SYMBOLIC LINK MECHANISM IS NEEDED TO INSURE THAT THESE RELATIVE
  2372. SEARCHES ALWAYS FOLLOW THROUGH CORRECTLY.
  2373.  
  2374. 2.7.5. ─┼╓╔├┼ ╙┼╥╓┼╥╙
  2375.  
  2376. ─EVICE SERVERS ARE JUST ANOTHER TYPE OF FILE SERVER, EXCEPT THEY CONTROL A
  2377. SPECIFIC DEVICE OTHER THAN A REGULAR DISK DEVICE, AND THEY ARE LIKELY TO
  2378. SUPPORT SOME CUSTOM OPERATIONS AND RETURN ERROR CODES IF SOME DISK OPERATIONS
  2379. ARE ATTEMPTED.  ╘HE INTERFACE IS IDENTICAL TO A FILE SERVER FOR CONVENIENCE.
  2380.  
  2381. 2.7.6. ├╧╬╙╧╠┼ ╙┼╥╓┼╥
  2382.  
  2383. ╩UST A SPECIFIC DEVICE SERVER.  ╔T HANDLES WINDOW MANAGEMENT AND CONSOLE
  2384. CALLS, LIKE ╫IN├LEAR, ╫IN╨UT, ╟ET╦EY, AND ├ON╫RITE, THAT ARE USED IN ┴├┼.
  2385.  
  2386. 2.8. ┴╙┘╬├╚╥╧╬╧╒╙ ┼╓┼╬╘ ╚┴╬─╠╔╬╟
  2387.  
  2388. ┴S MENTIONED IN THE ╨ROCESS SECTION ABOVE, THERE ARE MANY EXTERNAL EVENTS
  2389. THAT A PROCESS MAY HAVE TO WAIT FOR, INCLUDING:  MODEM CHARACTERS, DISK DRIVE
  2390. OPERATIONS (IF THEY ARE CUSTOM-PROGRAMMED CORRECTLY), MOUSE & JOYSTICK
  2391. MOVEMENTS, AND REAL-TIME DELAYS.  ╘HERE WILL BE AN ┴WAIT┼VENT() KERNEL
  2392. PRIMITIVE TO ALLOW A PROCESS TO WAIT FOR ONE OF THESE EVENTS TO HAPPEN.
  2393. ╬ORMALLY, THE ONLY PROCESSES THAT WAIT FOR THESE EVENTS WILL BE DEVICE
  2394. DRIVERS.  ╘HE KERNEL WILL ALSO HAVE TO DO SOME LOW-LEVEL PROCESSING FOR OF
  2395. SOME DEVICES (LIKE THE MODEM AND KEYBOARD) TO INSURE THAT THINGS DON'T BECOME
  2396. UNNECESSARILY INEFFICIENT.
  2397.  
  2398. 3. ╦┼╥╬┼╠ ─┼╙╔╟╬
  2399.  
  2400. ╬EXT TIME.
  2401.  
  2402. 4. ╙┘╙╘┼═ ╙┼╥╓┼╥ ─┼╙╔╟╬
  2403.  
  2404. ╬EXT TIME.
  2405.  
  2406. 5. ┴╨╨╠╔├┴╘╔╧╬ ╨╥╧╟╥┴═ ╔╬╘┼╥╞┴├┼
  2407.  
  2408. ╬EXT TIME.
  2409.  
  2410. ╘HIS IS QUITE SIMILAR TO THE ┴├┼-128/64 ╨ROGRAMMER'S ╥EFERENCE ╟UIDE, WHICH
  2411. IS AVAILABLE VIA ANONYMOUS ╞╘╨ FROM "CCNGA.UWATERLOO.CA" IN FILE
  2412. "/PUB/CBM/OS/ACE/ACE-R10-PRG.DOC".  ╥ELEASE #10 OF ┴├┼ WAS THE MOST CURRENT
  2413. AT THE TIME OF WRITING THIS ARTICLE.
  2414.  
  2415. 6. ├╧╬├╠╒╙╔╧╬
  2416.  
  2417. ╬EXT TIME.
  2418.  
  2419. ╔MPLEMENTATION: SOMEDAY, MAYBE.
  2420.  
  2421. ==================================================================---┼╬─---===
  2422.